Open-sourcing the Blue Style Guide for Julia

I was originally taught the 80 rule but I’ve created my own 80-92 rule since using Julia where 80 is a softwrap and 92 is a hard wrap. I’m not sure if this comes of as just inconsistent but it certainly seems to be a more manageable way of doing things.

I guess an off-topic, but breaking or not has to be judged w.r.t exposed API. It is conceivable to expose type API with trailing type parameters being explicitly documented as an implementation detail. This would mean that API-conforming downstream code can only use the types as an upper bound. But I guess it’s not a popular idea.

Thank you for this! I might adopt it in my packages. The style guide is quite extensive and I’ve only skimmed it, but I haven’t found a single major thing I disagree with so far. Everything seems to make sense; it shows that it has been battle-tested. I like that it’s not just blindly based on another language’s / company’s style guide, and I also like that it leaves some wiggle room.


Hurray! I really hope some people will find this useful. It’s at least helped me get used to a consistent way of writing code without having to think about format, and mostly removed style discussions from PRs.

By the way, while I don’t know where the 92 line length originates from, Python’s Black format (which uses 88) points to this video recommending “90 ish”.

(Possibly the precedent for shorter line lengths comes from punch cards.)

1 Like



This is a very detailed style guide. Thanks for making this public.

Most of the recommendations are very sensible, but I see the following done differently in a lot of packages.

  1. long argument lists

    # Blue Style
    function foobar(
    # break then indent (note matching indentation, break before 92
    function foobar(df::DataFrame, id::Symbol, variable::Symbol, value::AbstractString,
                    prefix::AbstractString = "")
  2. making trailing commas mandatory various expansions (after a while, the code settles and then they are not needed)

  3. insisting on no space around = in keyword arglists/named tuples; it provides a nice visual separator

  4. not using DocStringExtensions.jl (this produces a lot of repetition in docstrings that will go out of date)

  5. insisting on return for the last value (tends to be left out in a “lispy” style)

(This is not intended as criticism, just a list of differences.)


Actually we do use it in LibPQ.jl, and it is indeed very nice. It’s certainly compatible with the Blue style :slight_smile:

1 Like

You may want to import the functions from the module Foo without bringing them into the scope of Bar, so that you can make the function Bar.f without having to take into account what methods of Foo.f exist — e.g. if you don’t want to extend Foo.f with new methods, but create your own function with the same name, which might have a completely different purpose.


You can do using Bar: Bar.


Also, using Foo: f allows one to be lazy and write f unqualified. On the other hand, import Foo requires that I qualify all symbols from Foo, which is what I want when using Foo in another module.

Don’t write that then… (using Foo: Foo)


I find import Foo more clear than using Foo: Foo. But, if you can really do everything with using, then the small loss in clarity is worth the simplicity obtained by ditching import.


Apparently, this is not a minor issue. I just googled: julia difference between … (I was not looking for import and using), but it autocompleted to “using and import”.


The style I use concerning using/import is to always using and the exact additions to the namespace. I only qualify when there is ambiguity ( / I only extend functionality to functions that are brought by import Pkg: method_I_will_extend. I like the distinction and safe approach that follows.


The thing I don’t like about import Foo: bar is that then in some other place in the code you see function bar(x::MyType) ... end and it’s not very explicit that you’re extending some other package’s function rather than defining your own. I prefer to have function ... end whenever I’m adding a method to another package’s function.


The counterpoint would be that you can see every single function being extended in one place rather than go hunting across files to figure that out.

Not so. Do a “Find in the project” of for instance Base.count (when extending count). It pops up readily.
I think it would be harder to find if count wasn’t prefixed with Base.

1 Like

You would have to do so for every function for every module (Base, Core, stdlibs, submdules, transitive deps, etc.). I like being explicit in one place rather than explicit each instance, but everywhere.

Just a suggestion: you could use GitHub releases to set up a versioning scheme for the style guide. That way users can point to a specific version, rather than having a moving target (as the language itself continues to develop as well).