Open lucasteles opened 2 years ago
op_Implicit
after https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1093-additional-conversions.md is applied to functions and methods, so that would create a precedent for extending Func<'b>
and Func<'a, 'b>
, and Action<'a>
from methods to functions.
Aside from consistency, I don't think it's a large advantage as applying to methods tends to push the F#/.Net conversions to the boundary of F# code which is a good thing.
I'm strongly against any implicit conversion to Delegate
. The fact that Delegate
requires extra effort is a good thing, since any use of nongeneric Delegate
s is a code smell (potential for type errors) and this should be visible. Ideally the extra code should have the word Delegate
but Func<>
is still better than nothing. Even better - in the future when we have analyzers - an analyzer warning.
@charlesroddie I had the same feeling about Delegate
. but I changed my mind because I don't see it being used a lot even in C#.
I start to think about Delegate
like an obj
for functions.
this would remove the need for typing in aspnetcore pipeline correct? as the delegate would be inferred automatically, that would be awesome..
what about Task
would be easier also to have "automatic translation" of Task
.Use(fun httpContext (next: RequestDelegate) ->
task {
do! next.Invoke(httpContext)
} :> Task
)
@jkone27 I believe this https://github.com/dotnet/aspnetcore/pull/46898 will do the work for that
@charlesroddie I had the same feeling about
Delegate
. but I changed my mind because I don't see it being used a lot even in C#. I start to think aboutDelegate
like anobj
for functions.
Use of obj
(for improper purposes, i.e. for purposes other than ToString
/GC) is highly suspect and F# is looking into analyzer strategies to allow users to be warned about uses of obj
apis: https://github.com/dotnet/fsharp/issues/16219#issue-1973994013 .
Delegate
is worse as it doesn't have the valid uses that obj
has. Delegate
should not be allowed to creep in to F# code more than necessary - only at the edges where required by bad apis. Implicit conversion works against this so should not be allowed. Any allowance of this needs to be off by default or warn by default.
If we do this, which will change the semantic around method resolution with delegates arguments, it would make sense to tackle https://github.com/dotnet/fsharp/issues/11534.
is this going to make it somehow in F# 9? is there any general workaround or external library to adress this?
Please make implicit function cast. Here is the sample of ASP.NET minimal API.
app.MapGet("azureDevOpsTaskApi/GetApprovedDocumentByReleaseV2",
Func<
string,
string,
string,
string,
string,
string,
string,
AzureDevOpsApprovalTaskApiHandlerService,
Task<IResult>
>(
fun ([<FromHeader>]authorization: string)
([<FromQuery>]system_TeamFoundationCollectionUri: string)
([<FromQuery>]system_TeamProjectId: string)
([<FromQuery>]system_HostType: string)
([<FromQuery>]build_BuildId: string)
([<FromQuery>]release_DefinitionId: string)
([<FromQuery>]release_ReleaseId: string)
([<FromServices>]service: AzureDevOpsApprovalTaskApiHandlerService) ->
let input: RequestQueryV2 = {
System_AccessToken = authorization
System_TeamFoundationCollectionUri = system_TeamFoundationCollectionUri
System_TeamProjectId = system_TeamProjectId
System_HostType = system_HostType
Build_BuildId = build_BuildId
Release_DefinitionId = release_DefinitionId
Release_ReleaseId = release_ReleaseId
}
service.GetApprovedDocumentByReleaseV2(input)
)
) |> ignore
Marking as approved for the additional F# function to Func/Action conversions, with Expression also taken into account.
Some of these are present in F# already and careful examination will be needed to determine why they are not applying in all practical cases
There are also some other workarounds possible, see https://github.com/mchylek/Endpoints.FSharp.Interop/blob/main/samples/FSharpWeb/Program.fs for example.
The conversions to Delegate are approved too if further examples indicate they are really necessary, though @charlesroddie is right that, like obj, it's a total code smell that needs extra justification and a warning should perhaps be emitted by default. Anyone designing frameworks that routinely accept Delegate need to have a serious think about their choices in life - and reflect on whether they have earned the moral right to inflict that lack of strong typing on the universe.
Just to note: attributes in lambdas is a separate can of worms, and are not currently allowed (see discussion here: https://github.com/fsharp/fslang-suggestions/issues/984). So if we are to make conversion, it will still not going to work with attribute-based minimal APIs.
We might need to allow attributes for lambdas which are to be converted to delegates but not on the rest.
I'm introducing F# to some C# people using just .NET common frameworks and libs (Asp.net, EF Core, etc), I know that we have a lot of very good libs made to be functional friendly. But I saw a bit of cognitive load to people that already know very well common .NET stacks and are learning functional programming and having to learn other libs with it.
This proposal/discussion is about one pain point I saw in this process, which is how F# deals with Func<>, Delegates, and Action<>, which are the common way to express lambdas and some functional style APIs in .NET.
I think the easiest case to show is trying to use the new ASP.NET 6 minimal API.
This kinda thing happens when doing stuff with other libs like EF too.
Other problem I see are some cases which at first glance looks inconsistence:
So, the idea of this proposal is to minimize or remove this friction with the BCL. Allowing these functions to be cast implicitly.
I know that we dislike this kind of implicit casting, but I feel in this case It would be good, almost the same case as task and async
UPDATE:
For the same purpose I would like to put
Expression
in this discussion to:Pros and Cons
The advantages of making this adjustment to F# are we are removing learning noise and friction within .NET
The disadvantages of making this adjustment to F# are that it would be more implicit things.
Extra information
Estimated cost (XS, S, M, L, XL, XXL):
Related suggestions: (put links to related suggestions here)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.