Is the lambda->expression tree transformation process specified anywhere?
Asked Answered
G

2

8

There are two important steps to compiling a LINQ query in C#. The first is transforming LINQ query syntax into a chain of method calls, as described in section 7.16 of the C# language specification. This transformation process is specified in enough detail that a language developer can use it to implement similar query syntax on a new CLR language.

The second step is turning lambda expressions into expression trees, which takes place when calling a query method that returns IQueryable, but not when calling a method that returns IEnumerable. Is it ever specified how this transformation takes place, comparable to the explanation of the query syntax transformation process?

Geraldgeralda answered 5/11, 2014 at 2:28 Comment(0)
Y
5

Construction of expression trees is explicitly not defined, actually. Compiler developers are free to do use whatever approach they wish, provided of course that executing the expression produces the same result as invoking the lambda.

This is a quote from the C# Language Specification:


6.5.2 Evaluation of anonymous function conversions to expression tree types

Conversion of an anonymous function to an expression tree type produces an expression tree (§4.6). More precisely, evaluation of the anonymous function conversion leads to the construction of an object structure that represents the structure of the anonymous function itself. The precise structure of the expression tree, as well as the exact process for creating it, are implementation defined.


I added the boldface at the end.

I suspect that this was deliberately left unspecified to give compiler developers the freedom to implement whatever optimizations they find helpful. A rigid specification of the expression tree would prevent that.

Yaron answered 6/11, 2014 at 9:19 Comment(0)
R
0

Is it ever specified how this transformation takes place, comparable to the explanation of the query syntax transformation process?

As NSFW has stated, no.

On a practical, these expression trees can change from framework to framework. A real life example would be this:

We were using expression lambdas to get the property info through expression trees.

Such as void DoSomething<P, K>(P model, Expression<Func<P, K> propertySelector), and the usage DoSomething(model, m => m.Property)

The actual property interrogation was done inside DoSomething, through reflection. This is very classical, and variants of such code exists over the intenet.

Now, this is cool, it worked nicely in .NET 4.0. However, as soon as I tried 4.5, it blew up completely, as the underlying expression tree has changed.

You can be sure that Roslyn will introduce a lot new "bugs", in the sense that some client code relies on the representation how lambdas are translated to expression trees(If you really insist doing that - using Visitor class minimizes the chances of breaking).

Ensuring that the expression trees stay the same would be major task, and it would be also limiting(speed-wise for example)

Relation answered 6/11, 2014 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.