Skip to content
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

Support lambda literals for non-delegate types? #11929

Closed
eiriktsarpalis opened this issue Jun 10, 2016 · 8 comments
Closed

Support lambda literals for non-delegate types? #11929

eiriktsarpalis opened this issue Jun 10, 2016 · 8 comments

Comments

@eiriktsarpalis
Copy link
Member

We at the F# community have been investigating ways in which F# APIs could be made easier to consume from C# code. One of the primary pain points is that it currently is difficult to define literals for the F# function type. For those not familiar with F# functions, they are defined as classes inheriting the abstract type FSharpFunc<T,U> defined in the FSharp.Core library. This has been done to facilitate partial application, a feature common in functional languages.

The F# core library provides a set of implicit converters between the System.Converter<T,U> delegate and FSharpFunc<T,U>. One would expect that it should make it easy to declare F# function literals in C# like so:

FSharpFunc<int,int> func = x => x + 1;

However the code above fails with the message:

error CS1660: Cannot convert lambda expression to type 'FSharpFunc<int, int>' because it is not a delegate type

The error can be overcome by adding an explicit cast to the lamda

FSharpFunc<int,int> func = (Converter<int,int>)(x => x + 1);

which seems bizarre.

Would you consider enabing support for lambda literals in types that are not delegates?

@eiriktsarpalis
Copy link
Member Author

/cc @dsyme

@HaloFour
Copy link

How is this type generally consumed from C#? I assume that C# would be passing said function to a method of some exposed type? What kind of convention could C# recognize as a "lambda-like" as to not take any direct dependencies on any specific F#-types or conventions, and could F# adapt to a newly specified convention without breaking existing source?

@eiriktsarpalis
Copy link
Member Author

Any F# API that takes lambdas as parameters (think LINQ) is impractical to consume from a C# point of view.

One possibility would be to have the compiler infer the lambda literal type based on available implicit converters from delegate types to the assigned type at hand. This should work assuming no ambiguities arise.

@HaloFour
Copy link

Seems reasonable.

FSharpFunc<int,int> func = x => x + 1;
// translates into
FSharpFunc<int, int> func = FSharpFunc<int, int>.op_Implicit((Converter<int, int>)(x => x + 1));

@alrz
Copy link
Contributor

alrz commented Jun 11, 2016

Related to #4801

@HaloFour
Copy link

@alrz

That's true, such a modification to how lambdas are handled could introduce subtle breaking changes when it comes to overloading. I'd think that implicit operators would only be considered after any overloads with delegates have been ruled out.

@gulshan
Copy link

gulshan commented Dec 30, 2016

I think, there should be a static method fun converting C# lambda to F# functions like-

using static Microsoft.FSharp.Core.FSharpFunc;

var inc = fun(x => x + 1);

Type inferece will be an issue in this case though as @DavidArno mentioned here regarding implementation of similar feature in his SuccincT library-
https://github.com/DavidArno/SuccincT/wiki/TypedLambdas

In that case, the syntax will be either of these two-

var inc = fun<int>(x => x + 1);
/*or*/
var inc = fun((int x) => x + 1);

IMHO, C# team should be focusing more on type inference for cases like this.

@CyrusNajmabadi
Copy link
Member

Closing this out. We're doing all language design now at dotnet/csharplang. If you're still interested in this idea let us know and we can migrate this over to a discussion in that repo. Thanks!

@CyrusNajmabadi CyrusNajmabadi closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants