Julia Notes7 - Style Guild

Write functions, not just scripts

code inside functions tends to run much faster than top level code, due to how Julia’s compiler works.

Avoid writing overly-specific types

Code should be as generic as possible. This style point is especially relevant to function arguments. In fact, in many cases you can omit the argument type altogether, unless it is needed to disambiguate from other method definitions, since a MethodError will be thrown anyway if a type is passed that does not support any of the requisite operations. (This is known as duck typing.) The key thing to realize is that there is no performance penalty to defining only the general addone(x) = x + oneunit(x), because Julia will automatically compile specialized versions as needed.

Handle excess argument diversity in the caller


Append ! to names of functions that modify their arguments

It is typical for such functions to also return the modified array for convenience.

Avoid strange type Unions

Types such as Union{Function,AbstractString} are often a sign that some design could be cleaner.

Avoid elaborate container types

Use naming conventions consistent with Julia base/

  • modules and type names use capitalization and camel case
  • functions are lowercase, when readable, with multiple words squashed together (isequal, haskey). 可以用_分开
  • 少用abbreviation, 避免记忆负担
  • 名字太长, 应该想想是否应该分成几个concept

Write functions with argument ordering similar to Julia Base

  • function放前面, 这样可以使用do blocks
  • IO放前面
  • 会被修改的放前面
  • Type放前面, parse(Int, "1"), read(io, String)
  • Varargs放后面
  • Keyword参数放必须放最后

Don’t overuse try-catch

Don’t parenthesize conditions


Don’t overuse …

Instead of [a…, b…], use simply [a; b] 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.

Don’t use unnecessary static parameters

especially if T is not used in the function body. Even 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.

Avoid confusion about whether something is an instance or a type

Don’t overuse macros


Calling eval inside a macro is a particularly dangerous warning sign; it means the macro will only work when called at the top level.

Don’t expose unsafe operations at the interface level

Such a function should either check the operation to ensure it is safe, or have unsafe somewhere in its name to alert callers.

Don’t overload methods of base container types

# 不要这样做
show(io::IO, v::Vector{MyType}) = ...

users will expect a well-known type like Vector() to behave in a certain way

Avoid type piracy

“Type piracy” refers to the practice of extending or redefining methods in Base or other packages on types that you have not defined.

Be careful with type equality

You generally want to use isa and <: for testing types, not ==.

==一般只用于比较concrete type(e.g. T == Float64)

Do not write x->f(x)

x -> f(x)就是f

Avoid using floats for numeric literals in generic code when possible

try using literals of a numeric type that will affect the arguments as little as possible through promotion.

disruptive: Int < Rational < Float64

use Int literals when possible, with Rational{Int} for literal non-integer numbers