C # lambda expressions and lazy evaluation

One of the advantages of lambda expressions is that you should evaluate a function only when you need its result.

In the following (simple) example, a text function is evaluated only if there is a record:

public static void PrintLine(Func<string> text, TextWriter writer) { if (writer != null) { writer.WriteLine(text()); } } 

Unfortunately, this makes using the code a little ugly. You cannot call it with a constant or variable, for example

 PrintLine("Some text", Console.Out); 

and should call it like this:

 PrintLine(() => "Some text", Console.Out); 

The compiler cannot "output" the function without parameters from the passed constant. Are you planning to improve this in future versions of C # or am I missing something?

UPDATE:

I just found a dirty hack:

  public class F<T> { private readonly T value; private readonly Func<T> func; public F(T value) { this.value = value; } public F(Func<T> func) {this.func = func; } public static implicit operator F<T>(T value) { return new F<T>(value); } public static implicit operator F<T>(Func<T> func) { return new F<T>(func); } public T Eval() { return this.func != null ? this.func() : this.value; } } 

Now I can simply define the function as:

 public static void PrintLine(F<string> text, TextWriter writer) { if (writer != null) { writer.WriteLine(text.Eval()); } } 

and name it both function and value.

+7
lambda lazy-evaluation
source share
6 answers

You can use overload: -

 public static void PrintLine(string text, TextWriter writer) { PrintLine(() => text, writer); } 
+3
source share

I doubt that C # will get this function, but D has it. What you have outlined is a suitable way to implement a lazy evaluation of arguments in C # and probably compiles very similar to lazy in D and in cleaner functional languages.

All the things discussed, four additional characters plus additional free space, are not an exceptionally high price to pay for a clear resolution of the overload and expressiveness in what becomes a multi-paradigmatic strong language.

+3
source share

Unfortunately, ugly syntax is all you have in C #.

The "dirty hack" from the update does not work, because it does not delay the evaluation of string parameters: they receive an estimate before passing to operator F<T>(T value) .

Compare PrintLine(() => string.Join(", ", names), myWriter) to PrintLine(string.Join(", ", names), myWriter) In the first case, the lines are combined only if they are printed; in the second case, the lines are combined, no matter what: only printing is conditional. In other words, evaluation is not lazy at all.

+2
source share

It is good that these two statements are completely different. One of them defines a function, and the other a statement. Confusing syntax would be much more difficult.

 () => "SomeText" //this is a function "SomeText" //this is a string 
+1
source share

You can write an extension method for String to stick it on. You should be able to write "Some text .PrintLine (Console.Out); and let it do the work for you.

Oddly enough, I played around a bit with a lazy evaluation of lambda expressions a few weeks ago and talked about it here .

+1
source share

The compiler is very well versed in types, it is not good to infer intent. One of the hardest things about all the new syntactic sugars in C # 3 is that they can lead to confusion about what the compiler does with them.

Consider your example:

 () => "SomeText" 

The compiler sees this and understands that you intend to create an anonymous function that takes no parameters and returns the type System.String. This is all inferred from the lambda expression you gave him. Actually your lambda is compiled:

 delegate { return "SomeText"; }; 

and he is the delegate of this anonymous function that you send to PrintLine for execution.

This has always been important in the past, but now with LINQ, lambdas, iterator blocks, automatically implemented properties, among other things, it is extremely important to use a tool like .NET Reflector to look at your code after compiling it, to see what really makes you These features work.

+1
source share

All Articles