-
-
Save redbar0n/c011f0e0c682a9e1baf3f273fddf730c to your computer and use it in GitHub Desktop.
// The following is an example from the language Kitten, but generalizes to other languages. | |
// It should be useful for language design and choosing naming conventions for variables and functions. | |
// TL;DR: camelCase is most readable/discernable when used in context, as per this simple example extract: | |
`n bottles-of-beer on-the-wall` // kebab-case | |
`n bottles_of_beer on_the_wall` // snake_case | |
`n bottlesOfBeer onTheWall` // camelCase | |
// To more fully see the effect yourself, in context, do the following: | |
// Copy these examples into separate files, and switch tabs between them in your text editor, to compare them. | |
// To exacerbate the effect, squint with your eyes, and look especially at the contents of the `th_verse` function (google 'UX squint test'). | |
// Notice that `-` and `_` disappear, and become indiscernible from ` `. | |
// Notice that snake_case, while it reads best when a name is read in isolation (when not squinting), is inferior to camelCase when read in context. | |
// Because snake_case is too similar to whitespace, which makes it makes it hard to differentiate the separate keywords from one another. | |
// So camelCase comes out best. | |
// The full examples: | |
// snake_case: | |
99 bottles_of_beer_on_the_wall | |
define bottles_of_beer_on_the_wall (Int32 -> +IO): | |
-> n; | |
n th_verse | |
if (n > 1): (n - 1) bottles_of_beer_on_the_wall | |
define th_verse (Int32 -> +IO): | |
-> n; | |
n bottles_of_beer on_the_wall say | |
n bottles_of_beer say | |
take_one_down_pass_it_around say | |
(n - 1) bottles_of_beer on_the_wall say | |
newline | |
define bottles_of_beer (Int32 -> List<Char>): | |
bottles " of beer" cat | |
define on_the_wall (List<Char> -> List<Char>): | |
" on the wall" cat | |
define take_one_down_pass_it_around (-> List<Char>): | |
"take one down, pass it around" | |
define bottles (Int32 -> List<Char>): | |
-> n; | |
if (n = 0): | |
"no more bottles" | |
elif (n = 1): | |
"one bottle" | |
else: | |
n show " bottles" cat | |
// kebab-case: | |
99 bottles-of-beer-on-the-wall | |
define bottles-of-beer-on-the-wall (Int32 -> +IO): | |
-> n; | |
n th-verse | |
if (n > 1): (n - 1) bottles-of-beer-on-the-wall | |
define th-verse (Int32 -> +IO): | |
-> n; | |
n bottles-of-beer on-the-wall say | |
n bottles-of-beer say | |
take-one-down-pass-it-around say | |
(n - 1) bottles-of-beer on-the-wall say | |
newline | |
define bottles-of-beer (Int32 -> List<Char>): | |
bottles " of beer" cat | |
define on-the-wall (List<Char> -> List<Char>): | |
" on the wall" cat | |
define take-one-down-pass-it-around (-> List<Char>): | |
"take one down, pass it around" | |
define bottles (Int32 -> List<Char>): | |
-> n; | |
if (n = 0): | |
"no more bottles" | |
elif (n = 1): | |
"one bottle" | |
else: | |
n show " bottles" cat | |
// camelCase | |
99 bottlesOfBeerOnTheWall | |
define bottlesOfBeerOnTheWall (Int32 -> +IO): | |
-> n; | |
n thVerse | |
if (n > 1): (n - 1) bottlesOfBeerOnTheWall | |
define thVerse (Int32 -> +IO): | |
-> n; | |
n bottlesOfBeer onTheWall say | |
n bottlesOfBeer say | |
takeOneDownPassItAround say | |
(n - 1) bottlesOfBeer onTheWall say | |
newline | |
define bottlesOfBeer (Int32 -> List<Char>): | |
bottles " of beer" cat | |
define onTheWall (List<Char> -> List<Char>): | |
" on the wall" cat | |
define takeOneDownPassItAround (-> List<Char>): | |
"take one down, pass it around" | |
define bottles (Int32 -> List<Char>): | |
-> n; | |
if (n = 0): | |
"no more bottles" | |
elif (n = 1): | |
"one bottle" | |
else: | |
n show " bottles" cat | |
A curiosity that I just discovered (not that many program on their mobile phones, even though they share code gists and the occasional snippet on social media).
Typing effort on iPhone keyboard:
camelCase - 1 keyboard press required (shift key) before typing the first character of the next word (the capitalized c).
snake_case - 4 keyboard presses required (pressing the keyboard keys called: 123 then #+= then _ then ABC before being back and able to type the first character of the next word).
Typing effort on iPhone keyboard:
camelCase - 1 keyboard press required
snake_case - 4 keyboard presses required
Worth noting if you use the SwiftKey keyboard, holding Z will make an underscore, so pretty much the same effort as camel. Though if you camel case, autocorrect aggressively tries to break it into two words, but with snake case it doesn't (at least with SwiftKey on Android).
I still don't trust it though and don't do programming / wiki work on my phone to avoid getting autocorrekt :)
A counter-example (in C++) with regards to catching typos inside the names:
https://gist.github.com/EternalWill43/de507d054914277b8dbd2f8e73c757e7
But auto-complete ought to make such typos within variable or function names a non-issue, or atleast a very marginal one (compared to overall readability).
Maybe the optimal casing depends on the language (the most general context)?
Especially in how the language uses other symbols (or not) in separating variable or function names from surrounding code.
The prime thing to optimise for seems to be «lexical chunking» when reading.
(Reading > writing code, since code is read 10x as often as written. Although there is a limit to this; writing in one style ought not be significantly more effort than another.)