Fabulous Adventures In Coding
Eric Lippert is a principal developer on the C# compiler team. Learn more about Eric.
In my youth I once attended a lecture given by Brian Kernighan on the subject of code quality, which was very influential on my attitudes towards writing legible code. One of the things that Kernighan recommended was to endeavour write code that was so clear that it could be easily read over the phone and understood. Most people find code much easier to comprehend when read than when heard; if you can make it clear enough to be understood when heard, it's probably pretty clear code.
I was reminded of this when I got the following question from a colleague by email:
Subject: Stupid C# 3.0 lambda expression question
How does one read the => operator?
First off, I told my colleague that there are no stupid questions, only stupid people. No stupid people work here, so don't stress about it. This is a perfectly sensible question.
As far as I know, we do not have an "official" line on how to read this operator over the phone. In the absense of any other context, I personally would say c=>c+1 as "see goes to see plus one". Some variations that I've heard:
For a projection, (Customer c)=>c.Name: "customer see becomes see dot name"
For a predicate, (Customer c)=>c.Age > 21: "customer see such that see dot age is greater than twenty-one"
An unfortunate conflation is that the => operator looks a lot like ⇒, the "implies" operator in mathematics. Since => does not have the same semantics as ⇒, it is probably a bad idea to read => as "implies". (x⇒y would have the semantics of !x|y in C#.)
Incidentally, it is a little known fact that VB6 and VBScript implemented the ⇒ operator with the Imp keyword and the ⇔ operator with the Eqv keyword. They disappeared in VB.NET. Where did they go? It is a mystery!
I've actually been reading the => operator as "maps to". Stealing your example:
Customer see "maps to" see dot age is greater than 21.
Good one. Though I'd tend to use "maps to" for one-to-one transformations such as projections, rather than predicates.
I call it "rocket ship".
You probably don't want to know what I call the :- operator in Prolog...
I read the => operator as: "is used to get" or "are used to get" since items to the left of the operator are used as parameters in the expression that returns something.
"Customer see is used to get see dot Name."
"Customer see is used to get dot Age is greater than twenty-one."
(Customer c)=>c.Age > 21
"int ecks and string ess are used to get ess dot length is greater than ecks."
(int x, string s) => s.Length > x
(Customer c) => c.Name;
"[Given|For] Customer see, [return|yield] see dot Name."
Having thought about it a bit more, I'd substitute 'evaluate' for 'return|yield' to further differentiate it from a precompiled anonymous delegate:
"Given a Customer see, evaluate see dot Name."
"Yield' might be problematic in the future if we ever allow anonymous functions to be iterators. (Which I would dearly like, but is unlikely to happen any time soon.)
I give my vote to "maps to". Mathematically, a function maps values from A to B. In a way, you would rather be saying "customer see is mapped to a string via see dot name" or "customer is mapped to a boolean via see dot age greater 21"
+1 for "Given a Customer see, evaluate see dot Name"
"Maps to" and ilk directly translate to "Select", which is but one of the many uses of lambdas.
How about just lambda?
customer see lambda see dot name
This is one of the reason's I like VB. Our version Function(c as Customer) C.Name easily translates into "the function of C as Customer returns C dot Name". It is hard to find a VB line that doesn't read cleanly.
Does MSDN count as a source for "official" jargon? It refers to => as "goes to":
It is also hard to write VB lines that are terse.
I like "yield", but unfortunately C# already has a yield. I've been using "such that" quite a bit, but it doesn't really work in all cases.
Oh yeah, and I hate "goes to". Just sounds weird to me.