Mastodon Icon RSS Icon GitHub Icon LinkedIn Icon RSS Icon

Julia Revisited

Years ago, I wrote that Julia failed to reach any reasonable expectation. At the time, development was struggling, and the language had many problems trying to achieve any meaningful momentum.

Fortunately, time proved me wrong. And I am delighted I was. I am not sure what happened (as I said, I stopped following it), but the language had significant acceleration, and it finally got enough adoption and interest that it finally popped up a lot under my radar.

That’s why I decided to give the language another go. And what is a better opportunity than the Advent of Code? So, I did: I chose Julia as the language for Advent of Code 2021.

(And now, an Italian song that has nothing to do with Julia, other than the title.)

Strong Numerical Power

Many of the AoC problems were a perfect fit for Julia. As you may know, Julia is a powerful out-of-the-box closer-to-the-machine Python+NumPy. So if you can express your challenge in a way that involves matrices and linear algebra computations, Julia is the perfect candidate for the job. It produces unbelievably fast code, and it is effortless to work with.

Once I got familiar with the 1-indexed arrays (that remembered me of Lua) and the dot-broadcast notation (that remembered me of Matlab), I had no difficulty whatsoever with Julia and its pascal/FORTRAN syntax.

So, not only did Julia offer excellent performances, it was even straightforward to pick up blindly to tackle the AoC challenge. In some places, it really looked like cheating. Especially when I memoized a complex recursive function by simply adding the @memoize decorator.

I also enjoyed how easy it is to use math symbols to apply or define functions and variables. For example, being able to write n ∉ openlist instead of !(openlist.contains(n)) or !(n in openlist) gives a weird kind of pleasure to my mathematically inclined mind.

Some Painful Points

Yet, there are still painful points. Nothing serious, but they are worth noticing as a “new user.”

The first surprising issue was that Ctrl-C did not kill the running script in the terminal. That drove me insane, especially for a coding challenge in which it is very easy to get stuck in a loop or wait forever for the output of unoptimized code. Often, I had to close the entire terminal and reopen it. It was annoying. If there was a quick solution (other than coding a signal handler inside every script), I didn’t find it. That’s probably 100% on me, but it is the first time I have found a similar issue.

The second “issue” was that using the type system is not very ergonomic. Fortunately, everything is strongly typed, but everything is inferred. However, you may want to specify a variable’s type or a function’s parameters. The problem, in this case, is that defining the types is a bit lengthy. When in TypeScript, for instance, I can define a string array as foo: string[], in Julia, I need to write foo::Array{String,1}. And for complex types, it became annoying quickly.

But probably it is not even the verboseness. After all, Rust is not particularly clean with types, yet I have no problem with it. Nevertheless, a certain heaviness made me stop trying to be formally precise, and I ended up just using Julia as a non-type-checked dynamic language.

I also found it “weird” that Julia doesn’t offer a switch case or a match operator. A match, in particular, looks like the perfect fit for the language.

Conclusion

There are probably other things I am forgetting. But the point is: Julia is a viable language. If you work on scientific software, numeric models and data analysis, Julia is a surprisingly promising alternative to the the domain of Python and NumPy.

But, most importantly, I needed to write this article to redeem myself and this blog in the Julia blogosphere. :)