-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Improve C# to F# interoperability #1254
Comments
This seems a noble cause.
Wouldn't this break existing C# to F# 'interopers'? If someone has explicitly passed in a |
@rojepp the attributes do not change the method's signature, they merely allow for optional attributes to be omitted. If somebody passed all arguments in correct order, it would still work as before. |
@eiriktsarpalis I think this could made directly into an RFC - doing work in this area would be great. There may also be a set of op_Implicit or op_Explicit conversions that can help things from C#? |
@dsyme Implicit converters are enticing, however it looks like they do not work well with lambda literals. Using the System.Converter implicit converter we see that Converter<int, int> func = x => x + 1;
FSharpFunc<int, int> fsfunc = func; works as expected, however FSharpFunc<int, int> func = x => x + 1; complains with
|
@eiriktsarpalis Yeah it would be ideal if that worked. Perhaps add a Roslyn issue about it - Mads might actually do this. BTW is that with adding actual op_Implicit definitions to the FSharpFunc type? |
@eiriktsarpalis Oh yes, I forgot we had those already. |
@dsyme So you're saying we should ask the roslyn guys to enable implicit conversions for lambda literals? Or just support F# funcs? |
Btw, I just picked up from the internets that this also works but it looks a bit confusing: FSharpFunc<int, int> func = (Converter<int,int>)(x => x + 1); |
@eiriktsarpalis It would be up to the C# designers. This may be one instance of a more general problem they are encountering elsewhere (i.e. things that are lambda-like but aren't delegates). |
@eiriktsarpalis Of course preparing a PR to roslyn would help enormously. |
Maybe single method interfaces like Java 8 has ;-) From: Don Symemailto:notifications@github.com @eiriktsarpalis It would be up to the C# designers. This may be one instance of a more general problem they are encountering elsewhere (i.e. things that are lambda-like but aren't delegates). You are receiving this because you are subscribed to this thread. |
It would be nice to have |
Support an |
There's an existing uservoice about the first option: https://fslang.uservoice.com/forums/245727-f-language/suggestions/5663298-improve-optional-parameter-interop-between-f-and |
Having added 145! |
I'd really like to see progress on the optional attributes issue, perhaps in time for F# 4.1 (though the window is closing rapidly on that, partly because there's a considerable amount of other non-language work to get through in https://github.com/Microsoft/visualfsharp). I don't yet think I can prioritize it fo myself, though would welcome someone else fleshing out an RFC. |
That's correct. It might be interesting to do this for |
@dsyme I think though that those conversions might be dangerous since EDIT: Actually, scratch that first one, I read it in the opposite :) |
Surely it would only go one way i.e. FSharpList -> IEnumerable, and not the other way around? |
Pardon my ignorance, but what would it take for C# async to be able to return |
@isaacabraham they're already in a subtype relationship so this shouldn't be an issue. @smoothdeveloper C# computation expressions :-) Actually, there's a new Roslyn feature under way that might do just that. Look up the new ValueTask feature for more details. |
@dsyme I'd love to see optional parameter enhancements find their way in F# 4.1. I could create a PR. |
@eiriktsarpalis except as you said, IEnumerable is lazy whereas List isn't - the latter can safely go into the former but not the other way around? |
@isaacabraham It's potentially lazy. Lists, arrays and collections are instances of IEnumerable that are materialized whereas a state machine that produces infinite streams could be considered lazy. |
About lambda parameters: When adding delegate overloads to previously open System
open FSharp.Quotations
open System.Linq
open System.Linq.Expressions
type T() =
member this.X(f: int -> int) = 0
member this.X([<ReflectedDefinition>] f: Expr<int -> int>) = 1
member this.X(f: Func<int,int>) = 2
member this.X(f: Expression<Func<int,int>>) = 3
T().X(fun x -> x) // having any two overloads results in error When removing the If no other solution is implemented, it would be nice to at least have a priority resolution here, no errors if only one overload is found in the highest category, priority from highest to lowest:
If there are multiple parameters, it could use the one with the highest category. |
That compiled name attribute was also discussed on fable. I think it would be super useful. /cc @alfonsogarciacaro |
This is another thing which I find upsetting trying to use option from C# need to have this defined: http://www.fssnip.net/so/title/Make-option-type-usable-in-C All types from FSharp.Core should be reviewed to make their use easy from C#. |
would be very nice to turn FSharp.Options into nullables from a Record with compiler attributes from from F# side, or when marked with [] already convert options into nullables with default value null, so that methods/constructors have multiple overloads from c# side without many efforts from F# side, and also interface from C# point of view is nullables, options types (until c#7 or later) should be only considered a C# thing. it's quite weird to have to reference an FSharp.Core library from a c# project just to read a CLIMutable record with options type. would be much better if options are converted to nullables for interop, and then re-arrange nulls withing f# as it's much more easy. |
Closing old discussion |
I'm starting this issue to discuss potential changes that could improve C# to F# interoperability.
F# to C# interoperability works fine, but anyone who's ever used an F# library API from C# might have come across some of the following issues:
Optional parameters
Adding optional parameters to F# methods:
introduces an implicit dependency on F# option types:
this can be extremely off-putting for a non-F# user, and it gets worse as the number of optional parameters increases. The situation can be somewhat improved using this technique, but it still is a tedious exercise to decorate all possible optional parameters in your public api with proper attributes. Even if this is done correctly, overridden parameters would still have to be wrapped in
Some
.Here are a few potential fixes:
Lambda parameters
Public F# APIs that expose lambda parameters are virtually impossible to consume from other languages: users have to explicitly define a class that inherits
FSharpFunc<_,_>
which is extremely prohibitive.Here are a few potential solutions:
Conclusion
Please add any other interop issues that you might have come across. I firmly believe that the aforementioned issues seriously hurt widespread .NET adoption of good F# libraries. We can do much better than that.
The text was updated successfully, but these errors were encountered: