Functions are values: explore C# lambda types in Visual Studio

By Andrew Stellman
April 9, 2011 | Comments: 1

I love that a college professor of mine from long ago, Bob Harper, is tackling the tricky issue of how to teach students about the nature of functions in his new Existential Type blog. It's been—wow—over two decades since I took his 15-212 course at CMU. His post strikes a chord for me because I've spent a lot of time over the last few years thinking a lot about how to teach complex programming concepts to people who are learning from the ground up, which is what my third book, Head First C#, does reasonably well (in my totally unbiased opinion). Dr. Harper was an enormous influence and a real mentor to me when I was at CMU. He had a strong influence how I thought, learned, and grew, probably more than almost anyone else there during my student career.

Anyway, his post got me thinking about how you'd go about teaching this concept to a learner—specifically, in my case, a C# learner. I've given it a bit of thought, and here's what I've come up with. Obviously, it's not a complete guide to learning lambda expressions, but it's a possible starting point for people who are confused. If you're having trouble struggling with what exactly a lambda expression is, and especially if the question, "What's the value of a lambda expression?" seems bizarre, then this might be helpful.

For anyone who hasn't seen it, C# has a pretty rich syntax for lambda expressions. We didn't tackle them when we were working on the book—they were mostly out of scope for our readers, relegated to an appendix. But Dr. Harper's post inspired me to give some thought about exactly how I'd teach lambdas to people who are just learning programming concepts.

I think it's useful to start with the same problem that he started with. It turned out that a lot of his students got an exam question wrong:

What are the type and value of the expression (fn (x : int) => x div 0)?

After nearly every single student in the class got this question wrong, the course staff had T-shirts made up that said, "Functions are values," and in his post Dr. Harper ponders the question of how to do a better job teaching this concept. It's a very cool feeling for me to see him work through some of the same problems of teaching tough programming concepts, because I've spent many, many hours over the last few years doing exactly the same thing.

Head First C# CoverIt definitely makes sense to me that this is a tough concept to teach, even to very clever people (like CMU CS students). One of the things that I tried to do over the course of Head First C# was to make types "real" to our readers, through a combination of using them in lots of different ways, illustrating and even personifying them, and using the IDE to explore them.

That last bit is important. One big reason that I like C# as a teaching platform is that Visual Studio 2010 is a fantastic IDE, and more importantly, a great tool for exploring. It's also got an excellent pre-compiler type inference system which, when combined with the IntelliSense boxes that it displays when you hover over variables, can be really useful in explaining things. The reason I think C# would be useful for teaching students how to think about this particular problem is that it's a strongly type language that uses declared types - and lambdas are no exception.

So given all this, I gave some thought about the question Dr. Harper raised about how to teach lambdas to someone relatively new to a lot of these concepts. Specifically, I'd want to figure out how to make lambdas seem more "real" to the learner.

I'd start by just having them create a new console application, add these two lines to the Main() method:

int zero = 0;
Func myFunction = (x) => x/zero;

So first of all, this is where C# being strongly typed and having declared types makes it a good teaching tool. If you give a student a line of code like this: int myVariable = 123; —and ask what the type and value of that variable is, they'll tell you that it's an integer with the value 123. So now if you give them a line of code like this: Func myFunction = (x) => x/zero; —and ask them what the type and value of the variable is, there's a good chance that they'll at least have a good guess at the type.

This is the first opportunity to use the IDE to explore types. If you go into the IDE and hover over Func, you'll see an IntelliSense window pop up:

FunctionsAreValues screenshot 3.png

So the type that we're dealing with a delegate. A delegate is a type that references a method, and Head First C# readers will recognize from chapter 11. That's another reason I like C# for understanding these concepts: you get a specific name ("delegate") for the type of a lambda expression. Now, that's a somewhat tangled concept, and it took us a lot of trial and error to figure out a good approach to teaching it. But somehow having something "real" that you can play around with—and, more importantly, that you can explore with the IDE—makes it easier to understand.

The next thing I'd have the learner do—and I encourage you to follow along yourself!—is stick a breakpoint on the closing bracket of the method. If you're not a C# developer, here's a screenshot from Visual Studio 2010 Express (the free C# development IDE from Microsoft):

FunctionsAreValues screenshot 1.png

(The breakpoint is indicated by the red dot and highlight.)

For those of you who are following along, start debugging the program. When the breakpoint breaks, hover over the myFunction variable. This is what you'll see:

FunctionsAreValues screenshot 2.png

Here's why I really like using the IDE as a learning and teaching tool. By now, most learners have had a lot of repeated experiences where they want to find out the value of a variable, and do so by hovering over it and looking at that box. Well, now they've hovered over a variable that's got a lambda expression—and its value shows up in exactly the same place.

The reason that's an effective teaching tool is that it takes advantage of an important learning principle: it's easy to learn something if you group it with other, more familiar things visually. When a learner sees a method in the IntelliSense box that shows variable values, there's a good chance that he'll get that "a-ha" moment where the idea that the method itself is a value, and that value is assigned to a variable called myFunction.

Next, we'd break down exactly what that {Method = {Int32

b__0(Int32)}} means. It looks odd at first, but it's easy to break it into pieces:

  • Method = { ... } - that means this value is a method

  • Int32 - that's the return value, an int

  • <Main>b__0 - hmm, not sure what's going on there

  • (Int32) - that's the argument, an int

So what about that <Main>b__0 bit? Once you get past the intimidating greater than, less than, and underscores, there's Main (the method where this thing lives), and b__0. And it's not hard to figure out where b__0 comes from. Just add four more identical lambda declarations, except call them myFunction2, myFunction3, myFunction4, and myFunction5. Then debug the program again and hover over each of them, and you'll see they're called b__1, b__2, b__3, and b__4. So that's just a name that's automatically generated... which makes sense, because all methods have names, and you never specified one, so the compiler had to come up with one on its own.

So that's my starting point for how I'd use C# and experimentation with the IDE to teach a novice or intermediate programmer that functions are values.

There's one more thing I want to mention. I don't think I ever dropped Dr. Harper a note about it, but one of the exercises he assigned to us all those many years ago was the inspiration for an exercise that I created for our Head First C# readers. It's the exercise in chapter 8 where they create a Hide and Seek game and use it to explore a virtual house. He had us doing something similar, except in Lisp. We relied pretty heavily on teaching our readers through building video games, because it really helped motivate them to learn. I can definitely thank Bob Harper for helping show me that first hand all those years ago.

Andrew Stellman is the author of Head First C# and other books from O'Reilly. You can read more from Andrew at Building Better Software.

You might also be interested in:

1 Comment


News Topics

Recommended for You

Got a Question?