Abacus (59) [Avatar] Offline
#1
Jon,

On page 240, in Section 9.3.2, you say that "our simple addition expression is one that takes no parameters and returns an integer."

I find this statement completely mystifying. Doesn't the expression take two parameters, each of type int?

Could you please blow away the fog?

Thank you for your trouble.
jon.skeet (451) [Avatar] Offline
#2
Re: Expression Trees (Section 9.3)
The BinaryExpression node of the expression tree takes two parameters, but both of them are specified as constants. The overall result is an expression which doesn't take any parameters - which is why as a lambda expression it ends up as Expression<Func><int>> instead of Expression<Func><int,int,int>>. Notice how in listing 9.7 we call it with just compiled() - we're not specifying any arguments.

To put it another way - the addition expression will *always* add 2 and 3. You can't ask it to add two arbitrary numbers - unless you change it so that the arguments to the "add" node are parameters instead of constants.

Does that clarify it at all?

Jon
tomten (19) [Avatar] Offline
#3
Re: Expression Trees (Section 9.3)
Nice weather we're having!

Jon's answer was better. =]
Abacus (59) [Avatar] Offline
#4
Re: Expression Trees (Section 9.3)
Hi Jon,

Thank you for such a prompt response. That was practically instantaneous!

Your explanation makes sense. Thank you.
mgravell (64) [Avatar] Offline
#5
Re: Expression Trees (Section 9.3)
I hope you don't mind me jumping in, Jon.

The firstArg and secondArg variables are only arguments to the internal operation (Expression.Add); they aren't used as parameters to the lambda itself. For that, they would need to be ParameterExpression variables. To take arguments, the code would be more like (untested):

ParameterExpression firstArg = Expression.Parameter("x", typeof(int)),
secondArg = Expression.Parameter("y", typeof(int));
Expression add = Expression.Add(firstArg, secondArg);
Func<int,int,int> compiled = Expression.Lambda<Func><int,int,int>>(
add, firstArg, secondArg).Compile();
Console.WriteLine(compiled(2,3));
mgravell (64) [Avatar] Offline
#6
Re: Expression Trees (Section 9.3)
OK, that is kinda wierd! I only replied (after Jon) because at one point it looked like it wasn't resolved! Did a post get deleted?

Never mind.... sorry for interrupting, normal service about to resume [3][2][1]...

[edit] btw, I got the name and type the wrong way around: => (typeof(int), "x"smilie
But otherwise not bad from memory!

errata; Marc
jon.skeet (451) [Avatar] Offline
#7
Re: Expression Trees (Section 9.3)
> I hope you don't mind me jumping in, Jon.

Never smilie

> The firstArg and secondArg variables are only
> arguments to the internal operation (Expression.Add);
> they aren't used as parameters to the lambda itself.
> For that, they would need to be ParameterExpression
> variables. To take arguments, the code would be more
> like (untested):
>
> ParameterExpression firstArg =
> Expression.Parameter("x", typeof(int)),
> secondArg = Expression.Parameter("y",
> typeof(int));
> xpression add = Expression.Add(firstArg, secondArg);
> Func<int,int,int> compiled =
> Expression.Lambda<Func><int,int,int>>(
> add, firstArg, secondArg).Compile();
> sole.WriteLine(compiled(2,3));

Thanks for the fuller example. Given that some of this isn't entirely obvious, I'll add a note to the website including the code above and some form of the explanation from the comments here.

Jon
tomten (19) [Avatar] Offline
#8
Re: Expression Trees (Section 9.3)
> OK, that is kinda wierd! I only replied (after Jon)
> because at one point it looked like it wasn't
> resolved! Did a post get deleted?

I had that too, hence my editing of my reply. I think you need to reload the thread page alot, or there's some lag somewhere. Ah, now I see ".jsp" in the URL. ;]

null
Abacus (59) [Avatar] Offline
#9
Re: Expression Trees (Section 9.3)
Marc,

I appreciate your extra material. It is actually very helpful. This is my first encounter with expression trees, and I am finding this section of the book quite heavy going. So any extra detail helps.

I will undoubtedly have more questions on this topic, the answers to which will be obvious to those in the know, and welcome contributions from anyone with anything to say.

Eric (alias Abacus)
jon.skeet (451) [Avatar] Offline
#10
Re: Expression Trees (Section 9.3)
Expression trees are pretty hard to work with (unless you're Marc smilie - don't feel at all bad about just skimming over that section (and the next, which is pretty evil - I simplified it as much as I could, but type inference is just complicated...)

It's important to understand the basic premise of expression trees, and it's nice to have a clue about what the API looks like, but most mere mortals will only ever use them via lambda expressions, at which point the concepts are more important than the details.

Jon
mgravell (64) [Avatar] Offline
#11
Re: Expression Trees (Section 9.3)
Actually, when I first read section 9.3, I too was "huh? what? this is kinda hard". It is only when I started typing that it "clicked". I think maybe they are one of those things that you have to learn by doing... it also doesn't help that you need to think outwards - i.e. you have to start with the inner-most expression and build outwards - unlike regular code where you tend to think "left to right with a few brackets".

Marc
Abacus (59) [Avatar] Offline
#12
Re: Expression Trees (Section 9.3)
Jon,

Thank you for your interesting comment, which reminds me of some of the frustrations I had when studying physiology a few years ago.

The main reason why I am studying your book is that it provides more detail than others I have looked at so far. I have often found that books that try to simplify matters by omitting supposedly complicated details generally make them more difficult to understand.

I would actually like more depth and detail. I would be very interested, for example, in learning how high-level code is converted into CIL. For example, while I greatly enjoyed your explanation of the "yield return" statement, because, more than any other I have seen so far, it gave me a glimpse of what must be going on under the hood, I would be even more pleased to have the full works on how the compiler handles it.

Eric
jon.skeet (451) [Avatar] Offline
#13
Re: Expression Trees (Section 9.3)
> Actually, when I first read section 9.3, I too was
> "huh? what? this is kinda hard". It is only when I
> started typing that it "clicked". I think maybe they
> are one of those things that you have to learn by
> doing... it also doesn't help that you need to think
> outwards - i.e. you have to start with the inner-most
> expression and build outwards - unlike regular code
> where you tend to think "left to right with a few
> brackets".

I know you probably didn't mean it this way, but your reaction suggests that this section needs serious rewriting if/when there's a next edition (perhaps when C# 4 comes out?). I dare say it's difficult to explain it in a way in which it clicks before typing, but that's why authors actually get paid...

I'll see what I can do when the time comes.

Jon
jon.skeet (451) [Avatar] Offline
#14
Re: Expression Trees (Section 9.3)
Okay, I've created this note to try to help other readers:

http://csharpindepth.com/ViewNote.aspx?NoteID=131

Any feedback on that (or any other note) is most welcome, of course.
Jon
jon.skeet (451) [Avatar] Offline
#15
Re: Expression Trees (Section 9.3)
> The main reason why I am studying your book is that
> it provides more detail than others I have looked at
> so far. I have often found that books that try to
> simplify matters by omitting supposedly complicated
> details generally make them more difficult to
> understand.

True - and particularly irritating when it comes to parameter passing. Sorry, pet peeve.

> I would actually like more depth and detail. I would
> be very interested, for example, in learning how
> high-level code is converted into CIL. For example,
> while I greatly enjoyed your explanation of the
> "yield return" statement, because, more than any
> other I have seen so far, it gave me a glimpse of
> what must be going on under the hood, I would be even
> more pleased to have the full works on how the
> compiler handles it.

At that point I think the best tools are really Reflector and ildasm. I know that at several points writing the book I compiled some code and checked that it was doing what I expected by decompiling it. In the case of anonymous types, it wasn't doing what I expected - hence the note at http://csharpindepth.com/ViewNote.aspx?NoteID=14

It's nice to see other people who like to know what's going on "under the hood" so to speak. I hope you're enjoying the book!

Jon
Abacus (59) [Avatar] Offline
#16
Re: Expression Trees (Section 9.3)
Jon,

Thank you for your response.

I have downloaded Reflector, but do not know how to use it to decompile object files. I don't even know where my object files are stored! I am using Visual Web Developer 2008 Express. Can you give me any tips?

Also, can you refer me to a source that explains how to read CIL?

Thank you for your trouble.

Eric
jon.skeet (451) [Avatar] Offline
#17
Re: Expression Trees (Section 9.3)
Hmm... if you're using Web Developer Express things may be a little odd, but basically look for some DLL or EXE files underneath your project. Normally they'd be under bin/Debug or bin/Release, but it could all be different for web projects.

I suggest you download Visual Studio C# Express as well, so you can build normal console apps etc.

As for reading CIL - there's the ECMA spec (http://www.ecma-international.org/publications/standards/Ecma-335.htm) but I don't know of any tutorials etc. You can ask Reflector to decompile to IL, C# and VB - which is very handy.

Jon
Abacus (59) [Avatar] Offline
#18
Re: Expression Trees (Section 9.3)
Great note, Jon. Thank you. I only noticed it a minute ago. Eric
Abacus (59) [Avatar] Offline
#19
Re: Expression Trees (Section 9.3)
Jon,

Thank you for this information. I will follow up on it.

Eric
mgravell (64) [Avatar] Offline
#20
Re: Expression Trees (Section 9.3)
> but your reaction suggests that this section needs serious rewriting
It is up to you and your editor of course, but I was ultimately OK with that section. It /was/ a bit trickier than some, but I think that this is a necessary consequence of being a genuiney unfamiliar topic to most devs (unless you write a compilers / lexers for a living...).

So /personally/ I'd leave it alone; it works...
jon.skeet (451) [Avatar] Offline
#21
Re: Expression Trees (Section 9.3)
> > but your reaction suggests that this section needs
> serious rewriting
> It is up to you and your editor of course, but I was
> ultimately OK with that section. It /was/ a bit
> trickier than some, but I think that this is a
> necessary consequence of being a genuiney unfamiliar
> topic to most devs (unless you write a compilers /
> lexers for a living...).
>
> So /personally/ I'd leave it alone; it works...

Well, I'll see what I can do when the time comes - and borrow you for some consultancy smilie

Jon
Abacus (59) [Avatar] Offline
#22
Re: Expression Trees (Section 9.3)
Jon,

I found the note you posted to the book's Web site very helpful.

However, when I printed it, the text ran over the right margin (on American Letter format paper).

Eric
mgravell (64) [Avatar] Offline
#23
Re: Expression Trees (Section 9.3)
Did you see my comment about getting the name/type the wrong way around? Other that that it works. It might also be worth highlighting the need to also pass the parameters into Expression.Lambda.

Marc
jon.skeet (451) [Avatar] Offline
#24
Re: Expression Trees (Section 9.3)
> Did you see my comment about getting the name/type
> the wrong way around?

No, I missed that. Will take a look later this afternoon.

> Other that that it works. It
> might also be worth highlighting the need to also
> pass the parameters into Expression.Lambda.

Yup, good plan.

Jon
mgravell (64) [Avatar] Offline
#25
Re: Expression Trees (Section 9.3)
(see e-mail for a copy with comments, formatting, etc)
jon.skeet (451) [Avatar] Offline
#26
Re: Expression Trees (Section 9.3)
> I found the note you posted to the book's Web site
> very helpful.
>
> However, when I printed it, the text ran over the
> right margin (on American Letter format paper).

Did you use the "printable version" link? That should save a bit of space. I'll have a look later on though - I need to address one of Marc's comments anyway.

Jon
Abacus (59) [Avatar] Offline
#27
Re: Expression Trees (Section 9.3)
Jon,

Yes, I did.

Eric
jon.skeet (451) [Avatar] Offline
#28
Re: Expression Trees (Section 9.3)
Righto, I've fixed things up a bit with Marc's corrections, and also reformatted to hopefully make it easier to print.

Jon
Abacus (59) [Avatar] Offline
#29
Re: Expression Trees (Section 9.3)
Thank you, Jon. It looks great now. Eric