More concise lambdas that accept parameters by reference #4667
-
Consider the following piece of code: readonly struct MyStruct {
// ...
}
delegate void MyDelegate(in MyStruct s, int i);
void MyMethod(MyDelegate del) {
// ...
} It declares a read-only struct, a delegate that accepts a read-only reference of it, and a method that accepts this delegate. Such constructs are becoming more and more common in high-performance code that avoids needless data copyings. Before we continue, let's imagine how the code above would be used if delegate void MeDelegate(MyStruct s, int i);
void MyMethod(MyDelegate del) {
// ...
}
// We use both s and i.
MyMethod((s, i) => Console.WriteLine($"s: {s}, i: {i}"));
// We use only i.
MyMethod((_, i) => Console.WriteLine(i)); Everything is clean and simple, but not anymore. Because as soon as we pass MyMethod((in MyStruct s, int i) => Console.WriteLine($"s: {s}, i: {i}")); And God forbid if the types were longer (typing The proposalI propose to relax the compiler's rules and accept lambdas like the following: // We use both s and i.
MyMethod((in s, i) => Console.WriteLine($"s: {s}, i: {i}"));
// We use only i.
MyMethod((_, i) => Console.WriteLine(i)); On the first example, The second example takes it a bit further and does not require us to use the More details
MyMethod((in _, i) => Console.WriteLine(_)); but not this: MyMethod((_, i) => Console.WriteLine(_)); Of course we would not allow using
[<Struct>] type MyStruct = MyStruct
type MyDelegate = delegate of s: inref<MyStruct> * i: int -> unit
let myFunction (d: MyDelegate) = ()
// We use both s and i.
myFunction (MyDelegate(fun s i -> printfn "S: %A, i: %d" s i))
// We use only i.
myFunction (MyDelegate(fun _ i -> printfn "%d" i))
// And we didn't use any type annotations inside the lambda! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Dupe of #338, which i am championing. |
Beta Was this translation helpful? Give feedback.
-
I believe this is included in the proposed Lambda improvements lambda_expression
: modifier* identifier '=>' (block | expression)
| attribute_list* modifier* type? lambda_parameters '=>' (block | expression)
; |
Beta Was this translation helpful? Give feedback.
Dupe of #338, which i am championing.