Learning To Code Blog

Programming Languages Have Social Mores Not Idioms

I'm currently editing my Learn Ruby The Hard Way book and cleaning some things up here and there. In the process I've stumbled on what Rubyists call an "idiom", the use of .each to do loops instead of a for-loop. To them this is one of the most important signs that you are a real Ruby programmer. They look at this usage of one looping construct over another as some sign that you are incompetent, and haven't been properly indoctrinated into the Ruby community's ways. It's not just Ruby. Python, Java, every language has these weird "idioms" that denote your acceptance of their community standards. I'm just using Ruby's .each since it seems to be one of the most arbitrary yet vehemently demanded code constructs out there.

However, these are not idioms. An idiom is some little catch phrase that has meaning really only to people who grew up using it, and for everyone else it's some weird statement. An example is, "the whole ball of wax" to mean "the whole thing". Another is, "piece of cake" to mean "something really easy to do". These idioms are also not language dependent, but actually locality and culturally dependent. I could move to England, the home of English, and they'd use many new and different idioms.

What you don't see is people in England demanding that I say "the dog's bollocks" in order to visit. They also wouldn't go running around demanding you use the idioms instead of regular language. If programming idioms were actual idioms people wouldn't care if you used them or not. They would probably also adapt their coding style so you could read what they wrote instead of relying heavily on weird coding phrases. Because people quite literally freak out when they see non-idiomatic code, and go to great lengths to correct everyone who doesn't write idiomatically, these can't be idioms.

There's other problems with calling Ruby's .each an idiom when it comes to style. When you teach English writing, you tell people to avoid idioms unless it's something a character would say. You do this because unnecessary idioms obfuscate the text and make it harder to read, even for people not from your little part of the world. In these programming idioms it's the exact opposite. People nearly demand that you use these idioms in your code and even go so far as to never teach the alternatives to the idiom. These programming idioms can't actually be idioms if that's the case.

Imagine I wrote a technical paper for an English class with the sentence, "Configuring the module is a piece of cake, and I'm not pulling your leg." A good English teacher would tell me that sentence has too many idioms and I should change it. A good replacement would be, "Configuring the module is easy." If programming language idioms were idioms you would see other programmers telling people to remove them from good clean code in the same way that an English teacher would tell students to remove unnecessary idioms.

If Not Idioms Then What?

If these things we're calling idioms are nearly required, and people are judged for not using them, then they can't be idioms. Based on the crazy amount of yelling I receive over and over again from people in the Ruby community over something as incredibly minor as .each vs. a for-loop, I can tell you these are definitely not idioms. There has to be another word for what these are, and that word is "mores".

A social more is something that is demanded by a society to a level that it is nearly illegal, offends almost everyone, and people go out of their way to correct you if you violate it. These social mores many times become laws, and if not are taboos for that culture. They are very culturally dependent and not really a trait of language. Curse words are a great example of a social more that's part of the language, but many others have no language component.

If you read the wikipedia page on mores you start to see that what everyone calls "idioms" in programming are actually social mores for that particular language's community. What makes a social more different is in how they are demanded of the participants of a community and considered taboo. Idioms aren't taboo, and if a phrase becomes taboo (as with curse words), then it has become a social more to not say it anymore. You very rarely find idioms that are required social mores.

The fact that these particular forms of code are demanded, identify you as an outsider, and extract an impassioned reply from the community is proof they are actually social mores. They may have started as idioms, but once they become a requirement they are mores.

I might even go so far as to say programming languages don't have idioms at all. By definition an idiom is something you remove from good clean writing. Since these coding forms are more like social mores and expected of good clean code, they just can't be idioms.

Teaching Social Mores Is Indoctrination

When I teach people to code in my books I actually go out of my way to protect them from indoctrination. To me indoctrination is the enemy of education because it creates people who can't think for themselves and can only function in the culture they've been raised. It makes them into little mental slaves that can't question what's going on and see the world for what it really is.

Instead I want people who will question the way things are, try to find out how things are really built, explore the world and build new stuff without worrying about whether they'll anger some community. They can't do this if their thinking is constrained by these arbitrary social mores that only exist to keep them in line with what the community wants, or worse what the leaders of the community want.

When you teach people social mores as if they are universal truths you are actually indoctrinating them not educating them. When Ruby people teach that .each is better than for-loops they are doing indoctrination. When Python people demand that there arbitrarily be no "magic" in their code they are doing indoctrination. I could go on for days with languages and the bizarre social mores they have for really no reason.

Every language has these, and they cripple programmers by making it so they can't work in other languages. You see it all the time, where a programmer comes to a new language and drags all his previous language's coding styles and social mores with him. You also see how it frustrates them and deters them from attempting the new language. You'll see Java programmers freak out that there's no braces in Python code. You'll see Python programmers freak out that there's magic in Ruby code. You'll see Ruby programmers freak out that there's inconsistency in Python method usage.

Then again, this is probably the reason these social mores are enforced and taught. If you make people use .each and nothing else, then they'll be crippled when switching to a language that doesn't have a blocks-to-functions concept. Teaching social mores as universal truths keeps people dependent on that language's use of them.

Keep in mind though I'm not saying teaching these social mores is wrong and should be avoided. I'm saying teaching them as if they are the universal truths is bad. I teach them too, but I teach them as if they are just arbitrary bullshit you need in order to code with other people who have been indoctrinated.

The significance of this is that as these languages die and shift in popularity, my students will hopefully be able to adapt and learn the new languages. If they were too wrapped up in these programming social mores then they'd have a hard time doing that and may just quit programming completely at the first major popularity shift.

Why .each Is A Horrible First Looping Construct

One final thing I'd like to mention is why I don't teach .each at first in my book. Let's take an example of code from a Ruby styleguide:

arr = [1, 2, 3]

# bad
for elem in arr do
  puts elem

# good
arr.each { |elem| puts elem }

Now let's break down the concepts I'd have to teach to show someone how .each and for-loops work. First let's do .each:

  1. Variables
  2. Arrays
  3. Enumerable
  4. Inheritance
  5. Mixins vs. Multiple Inheritance
  6. Message passing and dispatch.
  7. Function calls.
  8. Blocks passed to function calls.
  9. Yielding variables to blocks.
  10. Scope, specifically for blocks.

That is a massive truckload of concepts. In my teaching method I do have people type code and then have them trust me, but I eventually teach the concept as completely as I can. In my experience so far teaching OOP is one of the hardest things to teach and has to come last for total beginners. The above list of concepts is just too much to break down for a beginner who can't even find Terminal, let alone understand the message passed to an Enumerable from a mixin with a block.

How about for-loops:

  1. Variables
  2. Arrays
  3. if-statement
  4. goto or jumps

That's it, I can actually teach all of a for-loop and most any iteration with just these four things. There's no need for OOP, mixins, message passing, blocks, scope, nothing other than some variables, an if-statement, and a jump. More importantly, the for-loop concept works in nearly every language. It's a fundamental concept in how a computer works, and even the Ruby .each eventually becomes a for-loop in C code. Teaching a for-loop as the first looping construct makes for a more capable programmer who can learn other languages.

So when people are running around teaching the incredibly more complex .each as the one true way to do looping, they are actually enforcing a social more, and care more about community norms than the students. You aren't creating programmers, you're creating good little Rubyists.

To me this is nothing more than indoctrination, and if people are going to do it, then stop calling them "idioms". They are social mores. It's alright if you're teaching social mores, but teaching them as if they are truths is wrong.

blog comments powered by Disqus

Copyright 2011 Zed A. Shaw. All Rights Reserved. Powered By Software He Wrote.