I tried the Julia Language during a month

Hi, I’m Roland, machine learning engineer at Fabernovel and this December I have decided to rediscover the AdventOfCode adventure. AdventOfCode has offered an advent calendar every year since 2015 but instead of receiving a piece of chocolate every day, we receive a riddle (separated into 2 parts) that must be solved by coding. At Fabernovel, several of us have participated and it’s nice to share with others the blockers and solutions day after day.

This year, I chose to increase the difficulty a bit by solving the challenges in Julia, a programming language that I did not know at all. This was the opportunity to discover this language that some perceive as the successor of Python.

Julia’s choice is not random: it is recent, attractive and close to the Python language that I’m familiar with, so I expect not to struggle too much with it. It is apparently mathematically oriented, which makes it an ideal companion for algorithmic challenges. I can’t wait to see it!

Come on, let’s install Julia on my computer.

Julia installation

I did my challenge last year with Jupyter notebooks in Python and it went well. As a reminder, a notebook allows you to run separate pieces of code and have their results displayed on a single document. It is used a lot in data science: it is very convenient for testing things and having nice visualizations integrated into the code. I really want to do the same with Julia knowing that Jupyter’s “ju” designates Julia so it shouldn’t be too complicated to install! (“pyt” for python and “er” for the R language).

I start Jupyter lab, dig a little and here is my first disappointment: no way to start a Julia kernel. I naively hoped that it would be installed as standard with Jupyter but nay. Going back to the documentation to install the Julia kernel: you first have to install Julia on your computer.

Binary

Nothing special here: I download the installer and it asks if I want to add Julia to my applications (I’m on Mac) so I accept. A double click on the program launches a terminal with Julia. However if I type julia in the terminal nothing happens so I add the path of the binary to my PATH in my .zshrc file.

Jupyter

Now that I have the language, I need to install the kernel for Jupyter. Ultra easy, it is done in 2 command lines inside the julia terminal.

using Pkg
Pkg.add("IJulia")

This is a bit weird: there is nothing else to do, no confirmation action on jupyter to “accept” this new kernel. So I nervously launch Jupyter and hurray, Julia notebooks are now available!

I quickly go through “Getting Started” to have at least the basic concepts in mind. I will be able to start coding while regularly consulting the documentation for this new language.

The Julia language: my impressions

Small leap in time: we are now in January. I have tackled the daily challenges one after the other but we will not dwell on this as it is not the purpose of this article. Much to my disappointment, I haven’t completed them all yet as they seem to be more difficult than last year.

I won’t either present the language in details (there are tutorials for that). As a Python developer, I will give you my feelings about this language and a list of the main things that stood out to me:

# Even if you are not a Julia programmer, I'm sure you can understand
function part1(numbers)
    counter = 0
    for i in 2:length(numbers)
        if numbers[i] > numbers[i-1]
            counter += 1        
        end
    end
    return counter
end
function part1(numbers::Vector{Int})::Int
    ...
end
items_except_first = items[2:end]
doyouthinkthisisagoodname = 42
# No import required to read the content of a file
lines = readlines("input.txt")
if x  valids && x  0
...
end
# mylist.push(element) doesn't work
push!(mylist, element) # works

I also find this choice very strong, but I understand it. Don’t get me wrong, I’m a huge fan of object oriented programming and I use it a lot, even in Python. But sometimes I think about functions with two or more variables: should I code a function / method f which is used like f(a, b), a.f(b) or b.f(a)? At least with Julia that question is settled.

# Compute the sum of integers between 1 and 10 and take the square root
composing = (sqrt  sum)(1:10)
piping = 1:10 |> sum |> sqrt

On the other hand I remain a little frustrated not to have found a method to make currying / partial applications. With all the battery of beautiful things coming from the functional world, it would have been perfect to be able to do that simply. But maybe I haven’t looked well enough.

result = "42" |> x -> parse(Int, x) # this works
result = "42" |> parse(Int) # sadly this doesn't work
f(x,y) = x + cos(y)
numbers = [0, pi, 2*pi]
a = map(z -> f(42, z), numbers) # a = [43, 41, 43]
b = f.(42, numbers) # same as previous line, b = [43, 41, 43]

In python, the NumPy library has also the concept of broadcasting. But it feels less like magic (and it’s more generic) in Julia.

Conclusion

Out of curiosity, I have checked what solutions the members of the Julia community shared on Github awesome-advent-of-code. I was not disappointed, it has nothing to do with the level of code I have produced. Even during the first days when the challenges are still simple, they use metaprogramming, obscure packages, they create modules and use complicated abstractions.

So, if you want to look cool when you code, you must:

I’m teasing a bit for the last few points, maybe I’m just jealous not to be as good as them in functional programming.

In any case, it was very pleasant to test the Julia language. It adapts very well to code puzzles. Unfortunately it is unlikely that it will dethrone the king Python. But I admit that I am impatiently awaiting the successor of Python: the language is a bit old and once you have tasted more recent languages (like Swift and Kotlin which I like a lot too), it’s hard to go back.

If you are curious, I have posted my solutions of the challenges on my GitHub. I do not guarantee that this code is the most efficient or that it uses 100% of the possibilities of the language but at least it is understandable by humans ;-)