Jaa


Reading Code Over the Telephone

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!

Comments

  • Anonymous
    May 16, 2008
    I've actually been reading the => operator as "maps to".  Stealing your example: Customer see "maps to" see dot age is greater than 21.

  • Anonymous
    May 16, 2008
    Good one. Though I'd tend to use "maps to" for one-to-one transformations such as projections, rather than predicates.

  • Anonymous
    May 16, 2008
    I call it "rocket ship". You probably don't want to know what I call the :- operator in Prolog...

  • Anonymous
    May 16, 2008
    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 c)=>c.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

  • Anonymous
    May 16, 2008
    (Customer c) => c.Name; "[Given|For] Customer see, [return|yield] see dot Name."

  • Anonymous
    May 16, 2008
    Having thought about it a bit more, I'd substitute 'evaluate' for 'return|yield' to further differentiate it from a precompiled anonymous delegate: (Customer c) => c.Name; "Given a Customer see, evaluate see dot Name."

  • Anonymous
    May 16, 2008
    "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.)

  • Anonymous
    May 16, 2008
    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"

  • Anonymous
    May 16, 2008
    +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.

  • Anonymous
    May 16, 2008
    How about just lambda? customer see lambda see dot name

  • Anonymous
    May 16, 2008
    The comment has been removed

  • Anonymous
    May 16, 2008
    Does MSDN count as a source for "official" jargon? It refers to => as "goes to": http://msdn.microsoft.com/en-us/library/bb397687.aspx

  • Anonymous
    May 16, 2008
    It is also hard to write VB lines that are terse.

  • Anonymous
    May 16, 2008
    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.

  • Anonymous
    May 16, 2008
    Oh yeah, and I hate "goes to".  Just sounds weird to me.

  • Anonymous
    May 16, 2008
    I usualy translate {ParameterList} => {Lambda Body} for given a {ParameterList}, {Lambda Body} with nothing in the middle but a comma.

  • Anonymous
    May 17, 2008
    For over a decade (and then some) I've written code in VB and I never found a use for Imp or Eqv even when I tried to invent one.  Perhaps thats the reason they're not in VB.NET ;)

  • Anonymous
    May 17, 2008
    The comment has been removed

  • Anonymous
    May 17, 2008
    So if you were reading a recipe to someone over the phone, you wouldn't say "add two tablespoons of baking powder", you'd say "add two T-B-S-P-S of baking powder"? My point, and Kernighan's point, which I seem to not have made very clear, was not about actually solving the problem of reading code over the phone to someone who is not fluent in the language. No one actually has to do that! Rather, it was intended to be a thought experiment that makes you think about whether the logic and structure of the code is sufficiently clear that it could be read aloud and understood WITHOUT having to write it down on the other end. So, for example, were I to read the code for (int i = 0; i < 10 ; ++i) Console.WriteLine(i); I'd read that aloud as "for eye from zero to nine, console dot writeline eye". That gets across the meaning of the code, which, after all, is what we're attempting to communicate. And then when reading it aloud, one might notice that foreach(int i in Range(0, 10)) Console.WriteLine(i); would ALSO be read aloud the same way. Which is good, because these two blocks of code express the same idea. It is precisely those expressions which cannot be read aloud and understood without spelling them out character by character and writing them down on the other end which are sufficiently hard to understand to warrant at least considering rewriting them to be more understandable.  

  • Anonymous
    May 17, 2008
    Just another "silly" question :-) how would you read Python code indentation over the phone ?

  • Anonymous
    May 19, 2008
    The comment has been removed

  • Anonymous
    May 19, 2008
    For a predicate, (Customer c)=>c.Age > 21: "customer see such that see dot age is greater than twenty-one" I would say "customer c where c dot age is greater than twenty-one"

  • Anonymous
    May 19, 2008
    So how well does the "c" read over the phone? What does see mean? Vision? Sea? Si (Spanish)? Yes dot name? The Atlantic ocean dot name? Or is it the Gulf of Mexico we're talking about? What is it with lambda expressions (and linq) that dictate that we should start writing unreadable code? Do you use variable names like "c" and "s" elsewhere? Especially with linq, when I look a query with all those single character variables I have to unnecessarily use extra brain cycles to map what those meaningless single char variables mean. I should be able to understand what every part of a lambda expression is doing without having to go back and map what those variables refer to. With intellisense and Resharper there's just no excuse to be writing code like that.

  • Anonymous
    May 22, 2008
    Rather than place the links to the most recent C# team content directly in Community Convergence, I have

  • Anonymous
    May 22, 2009
    30 years ago my brother, Mark, worked on a new HP desktop calculator called the 9825.  it had a new feature and a new button with a symbol much like "=>"; he named it the "gazinta" key.  (as in, "goes in to").  Why not create a new name for this feature and call it "gazinta"? +tom