julialangI’ve always had a soft spot for C because of its rawness, its history, and how much time I spent working with it during university. The type system is generous, memory is openly accessible, and parallelism requires forethought. Though I have worked in many other languages since then, none of them have ever gotten me inspired in the same way, until now.
Allow me to introduce the Julia programming language.

1. Syntax

Julia is homoiconic, which means that its code is isomorphic to the syntactic tree representation of the program it describes. In other words, there is a 1-to-1 relationship between symbols in Julia code and the logic they represent. An advantage is that it enables reflection, the ability Lisp is famous for, which is that code can write itself. Consider the example below where a convenient @foo macro is set up to catch errors.

julia> macro istrue(x)
           return :( $x ? nothing : throw(AssertionError($("DERP"))) )
       end
julia> @istrue 1==2
ERROR: AssertionError: DERP
 
julia> macroexpand( :(@foo 1==2) )             #the macro @foo expands into an if-clause
:(if 1 == 2
    nothing
else
    throw(AssertionError("DERP"))
end)

These macros are run at parse time because Julia can read its own code without a preprocessor. Think about all the hoops you normally have to jump through to do function overloading, for example. With macros you can automatically generate unique global functions per argument type.
Beyond meta-programming though, Julia code just looks good. 🙂
Check out this code for generating a Julia set fractal with the golden ratio:

h = 500; w = 1000                              # height and width of viewport
bitmap = Array(Gray24, h, w)                   # create an Array Gray24 pixels
detail = 150                                   # detailed level of the fractal
c = (φ-2) + (φ-1)im                            # phi as a UTF-8 variable
                                                 and imaginary numbers!
function fractal(z, c, max)
    for i = 1 : max                            # nice syntax for ranges
        abs(z) > 2 ? (return i) : nothing      # a terse if clause
        z = z^2 + c                            # complex plane arithmetic !
    end
    return max
end
for x = 1:w, y = 1:h                           # double nested for loop, nice
    z = (3*(x-w/2)/w) + (3*(y-h/2)/h)im        # just scaling the viewport
    out = fractal(z, c, detail)
    bitmap[y,x] = Gray24(1-out/detail)         # normalize Gray24 input to 1
end
view(bitmap)                                   # lets view the fractal!

fractal

2. Speed

As you might have guessed from the code above, Julia can be run interactively from a prompt because it uses a JIT compiler. In specific, it uses the high performance LLVM framework which allows Julia to approach and often match the performance of C.
Now, many languages claim to be “as fast as C” and are perhaps they are in some situations. Yet, you’ll find nearly all high performance libraries in R and Python that are written in C or Fortran. High performance Java code typically manages binary objects to avoid the JVM’s native object model. Moreover, it’s just really difficult to reason about performance in those languages. How many CPU cycles will a delegate call in C# take? Who knows.. With Julia, you can view assembly code for a code section instantly:

julia> add(x, y) = x + y
add (generic function with 1 method)

Julia> @code_native add(1, 1)
        .text
Filename: none
Source line: 0
        add     r0, r1, r0
        mov     pc, lr

Very cool if you ask me. There are additional welcome side effects of working through LLVM. The first is the potential to interoperate with other languages that use it. The best example is how Julia interoperates with C without any “glue code”. You want to call functions from your Nvidia CUDA dll? No problem. You can even do callbacks to Julia from C with support for pointers and everything.

const libcuda = Libdl.find_library(["nvcuda.dll"], [""])
macro cucall(fv, argtypes, args...)    #this macro makes using cucall convenient
    f = eval(fv)
    args = map(esc, args)
    quote
        _curet = ccall( ($(Meta.quot(f)), $libcuda), Cint, $argtypes, $(args...) )
    end
end

3. Modern

Despite being a language for technical computing – as its creators put it – Julia is surprisingly multifaceted:

  • Provides memory pointers and bit-twiddling functions for manipulating signals (like audio)
  • Supports UTF-8 very well and has Perl-compatible regular expressions (for string processing)
  • Synchronous interfaces with terminals, pipes, and TCP sockets (for shell-like tasks)
  • Provides a message passing model and co-routines (for concurrency)
  • Provides cluster management tools (for big data workloads)
  • Includes a package manager to add new functionality and features (like the Gadfly plot tool)

Naturally, Julia has nowhere near as big a community as popular languages like R, Python, or C#. It doesn’t have all the libraries and packages. It doesn’t have thousands of threads with code-examples on Stackexchange. It does have the right conditions to become great though.
Julia is open-source and distributed under the liberal MIT license. I appreciate this because it’s in the spirit of computer science, but more importantly, it is an important aspect that will allow the language to sustain its rapid growth. Companies like Nvidia, Microsoft, and scientists “in the know” are writing about Julia with an optimistic yet cautious tone. This is only the beginning, but it’s pretty awesome so far.