Camel case vs snake case

· Allanderek's blog

Musings on my extremely mild preference for snake-case over camel-case

Update: A couple of experiments that seem to give contradicting results for which case style is better for actually recognising identifier names: Camel > Snake and Snake > Camel.

Often when naming entities whilst programming we are forced to combine several words into a single lexical token. So instead of writing my function we have to call it my_function(snake case) or myFunction(camel case), or perhaps some other contortion, but these are the two most common.

Elm and Haskell both use, by convention, camel case. It's pretty clear that you should use whatever the convention is for the language you're writing code in. However, given the choice, I would choose snake-case. Here are the very minor points that I think give snake-case the advantage over camel-case.

# Abbreviations

Often, you need to include some kind of abbrievation in your name, such as HTTP, where that abbreviation is typically written in upper case. I feel this clashes with camel-case. Suppose you need to make a name out of a phrase such as "send HTTP request", in snake-case this translates pretty well as send_HTTP_request whilst in camel-case you would have to write either sendHTTPRequest or sendHttpRequest.

Neither of these options for camel-case seem great to me, but more importantly you have to make a choice, this means there is scope for different people to make different choices, which leads to inconsistency.

# Editor support

I have an nvim plug-in that allows me to operate on camel-case 'words' so for example if I have the cursor at the start of the word makeRequest and I type d\w this will delete 'make', rather than the whole 'word', and I can type c\wsend to change it from makeRequest to sendRequest. This is quite neat. I can still operate on the whole word as well dw would delete the whole makeRequest.

However, using snake-case, I don't need a plugin, this just works, admittedly I need to use dW to delete the whole make_request and the make_request might be part of a 'chain' such as make_request.foo.bar where I do not wish to delete after the ., but I can affect this with dt..

There are arguments both for and against the general solution here, but the point is, that with snake-case a reasonable solution just works out of the box, whilst camel-case requires a plug-in to even get started. Similarly in non-vim-based editors 'Ctrl+arrow' works pretty conveniently for snake-case and less so (in my opinion) for camel-case.

# Other Capital Meanings

Many languages distinguish the meaning of a word by the case of its starting letter. In Elm, modules, constructor, and type names all start with an upper case letter, whilst value names being with a lower case. In Go, if the first letter is uppercase the name is exported and not-exported otherwise. Whilst using camel-case doesn't prevent any of this (clearly since the convention in Elm is to use camel-case), it does mean you have two meanings of case in the same word. It's easy enough to get used to, but why?

# Qualifying

Occassionally you want to do something like qualify a name or unqualify a name. So you might want to turn something like request into mainRequest. In camel-case this involves changing a letter, but in snake-case (main_request) it involves only adding letters. Similarly you might be moving something like loginRequest into a more general function in which it is just a request and again making that change in camel-case involves changing a letter whilst in snake-case involves merely deleting some characters.

# Conclusion

So those are a couple of very minor points in favour of snake-case and I cannot think of any particular reason to use camel-case. Perhaps the underscore is inconvenient for some? I guess snake-case does mean that your names are longer. Anyway in general I find I can get accustomed to pretty much any (sane) syntax, even if I find it awkward to begin with. However, if I had the choice (and that would pretty much only been when designing my own language), then I'd opt for snake-case.