"At present, Julia is a/an ________ programming language. " Fill in the blank with the most appropriate adjective

Unfortunately, unless one just uses Julia as a generic Algol 60-like language (it has functions, control flow, …) without performance requirements, it is very easy to run into issues that require some experience and investment to solve.

As an experienced Julia user you are probably aware of all of these, but at the same time your experience makes it easier to avoid or fix them without a second thought.

To be concrete, let me give an example. The other day a student asked me for help with optimizing a calculation. Since it involved lots of small matrices, I immediately suggested using StaticArrays.SMatrix. The student then did something not unlike this MWE:

using StaticArrays

struct Foo{T,N}
    bar::SMatrix{N,N,T}
end

Now, seasoned Julia users can spot the problem quickly, which is easy to demo with

julia> baz(foo::Foo) = sum(foo.bar)
baz (generic function with 1 method)

julia> foo = Foo(SMatrix{3,3}(zeros(3,3)))
Foo{Float64, 3}([0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0])

julia> @code_warntype baz(foo)
MethodInstance for baz(::Foo{Float64, 3})
  from baz(foo::Foo) @ Main REPL[10]:1
Arguments
  #self#::Core.Const(Main.baz)
  foo::Foo{Float64, 3}
Body::Any
1 ─ %1 = Main.sum::Core.Const(sum)
│   %2 = Base.getproperty(foo, :bar)::SMatrix{3, 3, Float64}
│   %3 = (%1)(%2)::Any
└──      return %3

The problem is that SMatrix{3,3,Float64} is not a concrete type, it is SMatrix{3,3,Float64,9}.

Now imagine that you are a novice Julia user and this is buried deep inside 2k LOC, not a 3-line MWE you can just eyeball. You need to be aware of the tooling to discover where the problem is. Even better, set up CI with JET, and other QA tools. But then you are waist deep in… better call it experience.

Julia is immensely powerful, but if you want the performance, you cannot separate a “basic” part. It has rough edges and unravels quickly.

5 Likes