The current state of function naming style

I just came across this reply to a new package announcement. In it, they suggested removing underscores from function names to make them more idiomatic for Julia.

The question is, is Julia today still strictly abiding mashedcase naming? The SciML Style Guide suggested using snake_case, showing that the community and the core developers might have different opinions when it comes to function naming. In core Julia, it seems that snake_case is mainly used for internals only, but why be inconsistent?

I really want to know the community’s opinion on the current state of Julia function naming, in core code vs public packages vs normal code. To me, snake_case could seem too verbose, but the readability benefits might outweigh this. Has there been a general consensus on the topic?

There are lots of opinions; this has been discussed several times:

3 Likes

There is nothing wrong with using snake_case naming in the julia package ecosystem. Things like camelCase are seen as unusual though.

Julia Base itself has a self-imposed restriction that they try not to introduce any API names that are snake_case and instead use mashedcase, which is fine, but you’d be in good company if you decide you prefer snake_case, and should just ignore people complaining about it. It’s perfectly idiomatic.

3 Likes

From what I’ve seen, the style guide itself is quite ambiguous, unlike PEP8 which is more strict and definitive. I think it’s true that we don’t have the power to enforce anything, but having something more definitive to follow is quite less mental burden and more actual coding. I hate being too obsessed with code style! Maybe I’d just use snake_case regardless so as to reduce decision fatigue.

I disagree. If Julia Base promotes a certain code style, and the vast majority of packages sticks to it, I don’t see a very good argument to develop packages in different styles. At the end of the day, that would imply a spaghetti script with mixed code style from different packages:

using A # mashedcase
using B # snake_case
using C # camelCase

A.myfunc(B.my_const, C.otherFunc(B.other_const))

I think we won’t go as far as using camelCase for function names in Julia, mixing mashedcase and snake_case together could be bad but won’t be unhinged.

I would urge you not to use mashedcase. It is probably the worst style decisions that ever made it into Julia. The problem with mashedcase is that is does not scale: at some point, mashedcase becomes completely unreadable. Where exactly it crosses the boundary from ā€œreadableā€ to ā€œI have to include some underscoresā€ is pretty subjective. The result is that the names of functions become unpredictable.

My recommendation is to leave mashedcase for Julia core, and use snake_case consistently for functions throughout the ecosystem, and CamelCase for types and modules.

8 Likes

Even Julia Base had public API absurdly long like require_one_based_indexing though, which uses snake_case instead of mashedcase (it was an internal until it wasn’t, but the snake_case name is kept), the inconsistency is wild.

2 Likes

I have a hard time getting into the mindset of finding that to be a ā€œwildā€ inconsistency. At least to my eye, mashedcase and snake_case sit together side-by-side just fine, and which one I use really just depends on how clear or unclear the mashedcase version looks.

Might be a quirk of my psychology, or a result of being immersed in julia’s ecosystem where the two are often freely mixed. But I really just don’t get why people get worked up over this stuff unless it becomes an actual impediment to reading (which mashedcase does become past a certain length).

3 Likes

I follow this for all new functions, and only if I am extending existing functions (for me also just form Base ones) I of course continue their mashed case, e.g. for isapprox. In general I prefer snake for readability. Sure if mashedcaseinlongername is still unambiguous and readable, other package developers might also stick to that, but I do not like mashed. I think to some extend they can well live side-dy-side.

2 Likes

I personally prefer snake_case, but I think that choosing the actual name well (and in general, good API design) is much more important than this issue.

I fail to see why that is such a big deal. If someone actually likes camelCase, but they write a great package, with a well-designed API to boot, I will just happily use it. As for mashedcase, I would not bat an eyelid.

I have to agree, I believe I’m obsessing over this too much. But since I’m coming from languages that largely had consensus on naming styles, coming to Julia a few weeks ago, this definitely made me a little uncomfortable. I’m exaggerating the ā€˜wild’ inconsistency though, sorry for that.

1 Like

As a potentially helpful historical note, (that I might be misremembering), one reason that Base sets the mashedcase rule for itself was that they felt that for a Base language API, it would be a code-smell to have overly long, complicated, descriptive names.

A base API should be a common base of shared idiots that forms the language, and so they should be commonly recognized idioms, and relatively simple concepts. So using mashedcase forced the language API to choose shorter simpler names.

Packages are not the same. They are often for niche concepts, and are not providing concepts that everyone should be expected to know ahead of time in order to use the language. Therefore there are many cases where longer_more_descriptive_names are appropriate, and for that, snake_case just is a better fit.

5 Likes

Fair enough, the core developers’ decision rationales are good to know! I love the summary of the situation.

I’m sorry but that typo is quite funny. xD

8 Likes

lol, looks like I’m the shared idiot today. I’ll leave the typo up.

9 Likes

Yeah, I had a time where I did not like that one of my packages had ( and still has) isapprox and is_point – but by now I made my peace with that, exactly because I am fine with Base names being mashed and ā€œmineā€ being snake.

4 Likes