Firstly, we attempt to stick to the conventions from the . Most importantly, we write functions not scripts (see also Section 1.3). Furthermore, we use naming conventions consistent with Julia , meaning:
- Use camelcase for modules:
module JuliaDataScience
,struct MyPoint
. (Note that camel case is so called because the capitalization of words, as in “iPad” or “CamelCase,” makes the word look like a camel). - Write function names in lowercase letters and separate the words by underscores. It is also allowed to omit the separator when naming functions. For example, these function names are all in line with the conventions:
my_function
,myfunction
andstring2int
.
Also, we avoid brackets in conditionals, that is, we write if a == b
instead of if (a == b)
and use 4 spaces per indentation level.
The Blue Style Guide adds multiple conventions on top of the default Julia Style Guide. Some of these rules might sound pedantic, but we found that they make the code more readable.
From the style guide, we attempt to adhere specifically to:
At most 92 characters per line in code (in Markdown files, longer lines are allowed).
Avoid extraneous spaces inside brackets. So, write
string(1, 2)
instead ofstring( 1 , 2 )
.Global variables should be avoided.
Try to limit function names to one or two words.
Use the semicolon to clarify whether an argument is a keyword argument or not. For example,
func(x; y=3)
instead offunc(x, y=3)
.Avoid using multiple spaces to align things. So, write
instead of
Do not omit zeros in floats (even though Julia allows it). Hence, write instead of
1.
and write0.1
instead of.1
.Use
in
in for loops and not = or ∈ (even though Julia allows it).
- In text, we reference the function call
M.foo(3, 4)
asM.foo
and notM.foo(...)
orM.foo()
. - When talking about packages, like the DataFrames package, we explicitly write
DataFrames.jl
each time. This makes it easier to recognize that we are talking about a package. - For filenames, we stick to “file.txt” and not
file.txt
or file.txt, because it is consistent with the code. - For column names in tables, like the column
x
, we stick to column:x
, because it is consistent with the code. - Do not use Unicode symbols in inline code. This is simply a bug in the PDF generation that we have to workaround for now.
8.2.3.1 Loading of symbols
Prefer to load symbols explicitly, that is, prefer using A: foo
over using A
when not using the REPL (see also, ). In this context, a symbol means an identifier to an object. For example, even if it doesn’t look like it normally, internally , π
and CSV
are all symbols. We notice this when we use an introspective method from Julia such as isdefined
:
Next to being explicit when using using
, also prefer using A: foo
over import A: foo
because the latter makes it easy to accidentally extend foo
. Note that this isn’t just advice for Julia: implicit loading of symbols via from <module> import *
is also discouraged in Python (van Rossum et al., 2001).
The reason why being explicit is important is related to semantic versioning. With semantic versioning (), the version number is related to whether a package is so-called breaking or not. For example, a non-breaking update for package A
is when the package goes from version 0.2.2
to 0.2.3
. With such a non-breaking version update, you don’t need to worry that your package will break, that is, throw an error or change behavior. If package A
goes from 0.2
to 1.0
, then that’s a breaking update and you can expect that you need some changes in your package to make work again. However, exporting extra symbols is considered a non-breaking change. So, with implicit loading of symbols, non-breaking changes can break your package. That’s why it’s good practice to explicitly load symbols.