Being shouted at is not a lot of fun. So why do we shout in code?
Shouting code
Compare
"how_many_monkeys_can_a_monkey_eat_before_it_explodes"
and:
"HOW_MANY_MONKEYS_CAN_A_MONKEY_EAT_BEFORE_IT_EXPLODES"
How do you read those differently in your head?
We associate capital letters with someone shouting.
Now lets turn to two functionally equivalent pieces of Ruby code:
1 2 3 4 5 6 7 8 9 |
|
And
1 2 3 4 5 6 7 |
|
Constants are shouted. Why do we shout? Because:
We are angry
We have something we think is important and we want everyone to hear it.
Why in Ruby are constants uppercase? Well they don’t have to be, Ruby constrains us to ensuring the first letter is a capital. We get warnings if we try and reassign their value but ultimately they are just Fixnums. In order to stick with our Ruby naming convention we use ‘_’ and all caps.
So its a combination or telling the compiler that this value is a constant and fitting with the naming scheme in Ruby.
We shout because society indicates to us thats the normal behaviour and we all want to be nice citizens of the Ruby republic.
As a side effect constants feel like they are more important than the other variables or methods. They should take our attention first.
Reading uppercase is slow
What wait a minute isn’t uppercase text harder to read? There is evidence [1] to show that all-caps is less legible and less readable than lower case. So constants are harder for us to read.
lowercase permits reading by word units, while all capitals tend to be read letter by letter
Numbers, letters and uppercase
A common use of shouting case is constants used to remove magic numbers from calculations.
1000 * 667895 / LIMIT + 475436
The brain recognises numbers and letters very differently. The brain in general can recognise words faster than a sequence of digits since with a word we do not need to read each character in order to recognise the word.
To see for yourself try and read the following:
The hmaun mind does not raed eervy letter by istlef but the word as aa woelh.
Compare how much more time it takes you to read the numbers.
124 3456 3234 5443 3342 55334 66554 47567
By uppercasing the constant we are slowing down this natural ability to read words.
Compare again:
1000 * 667895 / LIMIT + 475436
With:
1000 * 667895 / limit + 475436
Do we really need this further uppercase difference? With the instinctive separation between words and letters the further effort and cognitive slow down has little value.
Immutability vs Mutability
A legitimate case were it does become useful to use shouting case is where you want to distinguish between variables/functions and constants. Expressing that a value is immutable in comparison to a mutable variable is important in a language like Ruby were immutability is not the norm.
1000 * 667895 + scale / LIMIT + 475436 - radius
Shouting in technicolor
Editors often provide color markup for words in uppercase. For example for Ruby in Textmate:
Though they also provide the difference between variables/function and numbers. Shouting provides us with a discernible way to see all constants within the code at glance based on colour.
History of shouting in code
How or where did this convention of uppercasing constants come from? Why is it a convention? When did we start shouting in our code?
What made us so mad?
Assembly
It started with assembly, the convention was to uppercase variables names and lowercase instructions.
ADCTL = 0x30
staa ADCTL,X
Variable names were limited in length, so often variable names were acronyms, which in English are often capitalised (we just skipped the dot). Registers, memory & caches all had nice acronyms which you could reference in your assembly.
Assembly was more machine centric than human centric. Not quite shouting as we know it now (though its understandable we were angry with all that ugly code).
FLOW-MATIC
The birth of programming in English. It was not a pretty birth, this thing was born shouting very loudly. EVERYTHING is in capitals, even the programming languages name!
INPUT INVENTORY FILE=A
PRICE FILE=B,
OUTPUT PRICED-INV FILE=C
UNPRICED-INV FILE=D,
HSP D.
Flow-Matic had the builtin in constant ZERO. Our first example of a Constant but where everything is capitalised so it is not distinguished from other code.
FORTRAN
FORTRAN was a confused language when it came to shouting. The use of lowercase letters in keywords was strictly nonstandard.
IF (IA+IC-IB) 777,777,705
IF (IB+IC-IA) 777,777,799
STOP 1
C USING HERON'S FORMULA WE CALCULATE THE
C AREA OF THE TRIANGLE
S = FLOATF (IA + IB + IC) / 2.0
AREA = SQRT( S * (S - FLOATF(IA)) * (S - FLOATF(IB)) + (S - FLOATF(IC)))
WRITE OUTPUT TAPE 6, 601, IA, IB,
STOP
END
But then the liberation came and after a bloody battle FORTRAN was renamed Fortran.
In this new post revolution age Fortran’s compiler was a liberal one, not caring about shouting or case at all.
program helloworld
print *, "Hello, world."
end program helloworld
The society on the other hand was still very keen to tell its citizens when they should shout. It was a social coding convention that local variables be in lowercase and language keywords be in uppercase.
Language keywords were more important and hence shouted. Far more important than those pesky human named local variables. This inverted the previous Assembly conventions on the use of case.
LISP
Common Lisp is case sensitive but the Common Lisp reader converts all uppercase to lower case:
(defun hi () "Hi!)
(hi) ;; outputs "Hi"
(HI) ;; outputs "Hi"
(Hi) ;; outputs "Hi"
LISP had a social convention to only use lowercase (one might think to avoid confusing situations like the one above). Did LISPeans shout at all? They did when it came to documentation strings:
“In a documentation string, when you need to refer to function arguments, names of classes, or other lisp objects, write these names in all uppercase, so that they are easy to find”
This was to help humans easily find them and because documentation generation tools could detect them.
Shouting the references in unstructured text made them clearly visible to both machines and humans.
COBOL
COBOL is another of those shouting languages which liked everything in uppercase. Which makes reading a COBOL program akin to having someone shout very loudly in your face. Until you cry. Lots.
01 RECORD-NAME.
02 DATA-NAME-1-ALPHA PIC X(2).
02 DATA-NAME-2.
03 DATA-NAME-3-NUMERIC PIC 99.
03 DATA-NAME-4.
04 DATA-NAME-5-ALPHA PIC X(2).
04 DATA-NAME-6-NUMERIC PIC 9(5).
02 DATA-NAME-7-ALPHA PIC X(6).
The only thing that was not upper case was comments.
It helps if all comments are in lower-case, to differentiate from actual commands which should always be in upper-case
Comments where not important, so no need to shout them. Which in turn makes them easier to read. Perhaps there is an understanding here that shouting makes code hard to read. Comments which might contain a lot of text should also be easier to read.
If you were still in doubt about COBOL’s evilness: user defined constants were distinguished by using a single character variable name. MAD. YES THAT WAS WORTH SHOUTING.
Basic
In basic keywords were capitalised to distinguish between variables names. The case is insignificant, it’s for the humans not the compiler.
LET m = 2
LET a = 4
LET force = m*a
PRINT force
END
Keys words are important, so shout them. But in turn make it easier to read the user named variables by leaving them lower case.
C
C uses uppercase by convention for object-like Macros which get replaced during pre-processing.
#define BUFFER_SIZE 1024
foo = (char *) malloc (BUFFER_SIZE);
Uppercase is used to defined a templating language within C, which we can quickly distinguish from the code. It also makes the job of the pre-processor easier, parsing macros.
So is shouting a bad thing?
When it comes to expressing ideas in nothing but text we use everything we can to provide structure and separation to help improve clarity. Shouting or uppercasing words provides a very powerful way of rapidly distinguishing certain aspects of text.
How programming languages spend this limited currency of instinctive separation reflects the languages understanding of readability (i’m looking at you COBOL) and what they find to be important enough to earn shouting case.
However most modern languages provide you with the choice of shouting. In Ruby we can skip it all together.
Try not shouting for a while. See how it makes you feel.
And always:
TRY AND AVOID SHOUTING FOR TOO LONG AS IT IS HARD TO READ.
Keep it sharp, short and loud.
References
[1] Type and Layout: How Topography and Design Can Get Your Message Across – Or get in the Way