Be Idiomatic
I have two or three drafts now that start with the meta of me apologizing for being sparse in my posting of late. TL;DR is that I’ve started a new, out of town engagement and between ramp-up, travel and transitioning off of prior commitments, I’ve been pretty bad at being a regular blogger lately.
Also, special apologies to followers of the Chess TDD series, but my wifi connection in room has just been brutal for the desktop (using the hotel’s little plugin converter), so it’s kind of hard to get one of those posts going. The good news is that what I’m going to be doing next involves a good bit of mentoring and coaching, which lends itself particularly well to vaguely instructional posts, so hopefully the drought won’t last. (For anyone interested in details of what I’m doing, check Linked In or hit me up via email/twitter).
What It Is to Be Idiomatic in Natural Language
Anywho, onto a brief post that I’ve had in drafts for a bit, waiting on completion. The subject is, as the title indicates, being “idiomatic.”
In general parlance, idiomatic refers to the characteristic of speaking a language the way a native would. To best illustrate the difference between language correctness and being idiomatic, consider the expression, “go fly a kite.” If you were to say this to someone who had learned to speak flawless English in a classroom, that person would probably ask, “what kite, and why do you want me to fly it?”
If you said this to an idiomatic USA English speaker (flawless or not), they’d understand that you were using a rather bland imprecation and essentially telling them to go away and leave you alone. And so we make a distinction between technically accurate language (syntax and semantics) and colloquially communicative language. The idiomatic speaker understands, well, the idioms of the local speech.
Being Idiomatic in Programming Language
Applied to programming languages, the metaphor holds pretty well. It’s possible to write syntactically and semantically valid code (in the sense that the code compiles and does what the programmer intends at runtime) that isn’t idiomatic at all. I could offer all manner of examples, but I’ll offer the ones probably most broadly approachable to my reader base. Non-idiomatic Java would look like this:
public void DoSomething()
{
System.out.print("Hello!");
}
And non-idiomatic C# would look like this:
public void doSomething() {
Console.WriteLine("Hello!");
}
In both cases, the code will compile, run, and print what you want to print, but in neither case are you speaking it the way the natives would likely speak it. Do this in either case, and you’ll be lucky if you’re just laughed at.
Idiomatic or Nitpicky?
Now you may think that, because of this simple example that touches off a bike-shedding holy war about where to put curly braces that I’m advocating for rigid conformance to coding standards or something.
That’s not my point at all. My point more goes along the lines of “When in Rome, speak like the Romans do.” Don’t walk in and say, “hey Buddy, give me an EX-PRESS-O!” Don’t be bad at speaking the way the community does and proud of it.
Here is a much more subtle and iconic example of what I’m talking about. Do you ever see people in C# do this?
if(null == x)
throw new NullArgumentException("x");
I once referred to this as “The Yoda” in an old blog post. “If null is x, null argument exception you throw.” Anyone know why people do this, without cheating? Any guesses?
Porting “The Yoda” From C to Other Languages
If you said, “it’s an old C/C++ trick to prevent confusing assignment and comparison,” you’d be right. In C and C++ you could do things like if(x = null) and what the compiler would do would be to assign x to null and then compare it to zero, which would result in it returning true no matter what x had been previously.
Intuitive, right? Well, no, not at all, and so C/C++ programmers got into the habit of yoda-ing to prevent a typo from compiling and doing something weird and unexpected.
And, some of them carry that habit right on through to other languages like C#. But the problem is, in C#, it’s pure cargo cult weirdness. If you make that typo in C#, the compiler just barfs. if(x = null) is not valid C#. So the C++ life-hack is pointless and serves only to confuse C# programmers, as evidenced by questions like this (and, for the record, I did not get the idea for my bloopers post name from Daniel’s answer, even though it predates the post — GMTA, I guess).
Don’t Port Idioms — Adjust To Your New Stack
So, if you’re doing this, the only upside is that you don’t have to change your way of doing things in spite of the fact that you’re using a completely different programming language. But the downside is that you needlessly confuse people. I suspect this and many other instances are a weird, passive-aggressive form of signaling.
People who do this might be saying, “I’m a C++ hacker at heart and you you can take my pointers, but you’ll never take MY CONVENTIONS!!!” And maybe the dyed-in-the-wool Java guys write C# with curly brackets on the same line and vice-versa with C# guys in Java. It’s the geekiest form of passive (aggressive) resistance ever. Or, maybe it’s just habit.
But whatever it is, my advice is to knock it off. Embrace any language you find yourself in and pride yourself how quickly you can become idiomatic and rid yourself of your “accents” from other languages.
Being Idiomatic is the Key to Getting Good Quickly
By really seeking out the conversion, you don’t just appear more versed more quickly, I’d argue that you become more versed more quickly. For instance, if you look around and see that no one in C# uses The Yoda, it might cause you to hit google to figure out why not. And then you learn a language difference.
And there’s plenty more where that came from. Why do people use more enums in language X than in language Y? Why do people do that “throws Blah” at the end of a java method declaration? What’s thing with the {} after a class instantiation in C#? Why is it okay in javascript to assign an integer to “asdf”?
If you’re new to a language and, instead of asking questions like those, you say, “these guys are stupid; I’m not doing that,” you’re balling up an opportunity to learn about language features and differences and throwing it in the trash. It’ll mean getting further out of your comfort zone faster, but in the end, you’ll be a lot better at your craft.
By the way, if you liked this post and you're new here, check out this page as a good place to start for more content that you might enjoy.
I tend to suspect what the passive “signaling” that you describe, in many instances. Regarding Yoda Notation, I have to think a normal person with a normal brain could be told one time that there is no value to needlessly reversing conditions any longer, and that person should be able to immediately adapt.
I suppose a person then might argue that the behavior is “habit,” but that’s a really, really poor justification for software development practices.
Completely agreed, and that’s what made me think of this particular example. Surely someone, at some point, would comment to a dev that it’s not necessary, so it becomes a purposeful declaration of “I like my old language and its way of doing things.”
Taking this example a bit further, I’m trying hard to learn how to think idiomatically when using functional programming language vs. an object oriented one. I’ve been trying out functional languages in an attempt to make myself more comfortable both with the syntax as well as the mindset when solving a problem “functionally.” Excellent post. Your comment about the passive-aggressive signaling hit me right between the eyes. I spent some time writing VB6 apps shortly out of college, and I insisted on using 2 apostrophes to prefix my comments since it reminded me more of the 2 slashes that C++… Read more »
I don’t know which functional language you’re focusing on, if any, but I appreciated this list of dos and don’ts so very much, and wish such guidance were more commonplace: http://fsharpforfunandprofit.com/learning-fsharp/
Heh. I remember doing the same thing for a while in my younger days in Java and possibly C#. I brought along the old, C-style (shown here: http://syque.com/cstyle/ch4.5.htm ) into those languages in spite of their conceptually better idea of XDoc comments. Silly, in retrospect.
Going across programming paradigms, I think, requires becoming idiomatic on a whole different level. Maybe, at the risk of straining the metaphor, it’s like going from English to Mandarin instead of Spanish to Italian.
[…] Be Idiomatic – Erik Dietrich […]
There may still be some cases with booleans in C# where Yoda is useful.
For example this compiles:
var someValue = false;
if (someValue = true)
{
Console.WriteLine(“pure cargo cult weirdness!”);
}
Wow, thanks for the tidbit. I never knew this worked with booleans; it’s not my style to say if(x == true) rather than if(x), so I never have occasion to run into it. Off the cuff, that one exceptional case seems an odd choice by the language authors, but I’m extremely hesitant to criticize language authors without a lot of research because there’s almost certainly some edge case I’d never think of that causes it to make sense.
Actually, in C#, assignment returns the assigned value. So we can create a getters like this:
get { return _value ?? (_value = “initial value”); }
And because a boolean is a valid expression in if statements, it doesn’t produce compiler error, as is the case with other types of values.
Thanks for the explanation. Makes a lot of sense. (This is exactly why I don’t make snap criticisms of language — I’m usually wrong, not them)
While this is correct, you shouldn’t compare Boolean values with true/false, but rather use
if (someValue)
or
if (!someValue)
So your example is not idiomatic. This is especially true in C or C++, since it is possible that a bool or BOOL variable can have a “true” value not equal to 1, which would fail when explicitly comparing to true/TRUE.
Small addition:
An explicit comparison with true/false can be necessary when using a nullable bool value. However, in that case an assignment will fail during compilation, since the result of the assignment is still nullable bool, which has no implicit conversion to bool:
bool? test = null;
if (test == true) // compiles
if (test = true) // does not compile
Daniel,
Quite right, and thank you for illuminating this important point!
I started out with the qualification “There may still be some cases” because I knew my example wasn’t a good one.
It’s a little scary that the equality can (and occasionally does) get mixed up with assignment in C# and this is a weakness in the language.
However after further reflection Yoda never seems to be part of the remedy I would recommend.
[…] Be Idiomatic (via Eric Dietrich) […]