The following sections explain a few aspects of idiomatic Julia coding style. None of these rules are absolute; they are only suggestions to help familiarize you with the language and to help you choose among alternative designs.
Code should be as generic as possible. Instead of writing:
convert(Complex{Float64}, x)
it’s better to use available generic functions:
complex(float(x))
The second version will convert x to an appropriate type, instead of always the same type.
This style point is especially relevant to function arguments. Don’t declare an argument to be of type Int or Int32 if it really could be any integer, expressed with the abstract type Integer.
Instead of:
function foo(x, y)
x = int(x); y = int(y)
...
end
foo(x, y)
use:
function foo(x::Int, y::Int)
...
end
foo(int(x), int(y))
This is better style because foo does not really accept numbers of all types; it really needs Int s.
Types such as Union(Function,String) are often a sign that some design could be cleaner.
When using x::Union(Nothing,T), ask whether the option for x to be nothing is really necessary. Here are some alternatives to consider:
It is usually not much help to construct arrays like the following:
a = Array(Union(Int,String,Tuple,Array), n)
In this case cell(n) is better. It is also more helpful to the compiler to annotate specific uses (e.g. a[i]::Int) than to try to pack many alternatives into one type.
If a function name requires multiple words, it might represent more than one concept. It is better to keep identifier names concise.
It is better to avoid errors than to rely on catching them.
Julia doesn’t require parens around conditions in if and while. Write
if a == b
instead of
if (a == b)
Splicing function arguments can be addictive. Instead of [a..., b...], use simply [a, b], which already concatenates arrays. collect(a) is better than [a...], but since a is already iterable it is often even better to leave it alone, and not convert it to an array.
A function signature
foo{T<:Real}(x::T) = ...
should be written as
foo(x::Real) = ...
instead, especially if T is not used in the function body. If T is used, it can be replaced with typeof(x) if convenient. There is no performance difference. Note that this is not a general caution against static parameters, just against uses where they are not needed.