dark mode light mode Search Menu


Do you think machine learning sounds cool? Does the phrase “scientific computing” make your ears perk up? Then you might be interested in learning more about a young, rapidly developing programming language called Julia.

Julia is a general purpose programming language, suitable for a wide variety of tasks but the big thing Julia is meant for is doing calculations fast. The designers wanted a language with better performance but that was as easy to program as something like Python.

What does that mean, though?

Let’s start by comparing the Python and Julia implementations of my favorite way of calculating pi.

The method is described well at this very 1990’s looking website here: http://mathfaculty.fullerton.edu/mathews/n2003/montecarlopimod.html This way of calculating pi is an example of a really common technique in scientific computing: the monte carlo method. If you’re interested in physics, you’re definitely going to come across this again!

The basic idea is pretty simple though: you can calculate pi by taking a square with a big circle inside it, like this…

…and then picking a bunch of random points, like throwing darts at the picture. If you take the number of darts that land inside the circle divided by the number of darts you threw then this is going to be equal to pi/4.

The very simple no-attempt-to-be-fast implementation of this algorithm in Python is:

import random
numTimes = 10000000
hits = 0
for i in range(numTimes):
    x = random.random() - 0.5
    y = random.random() - 0.5
    if (x**2 + y**2) <= 0.25:
	hits = hits + 1
print("pi is approximately: ", 4*hits/numTimes)

in Julia, on the other hand, it looks like:

hits = 0
numTimes = 10000000
for i in 0:numTimes
    x = rand()-0.5
    y = rand()-0.5
    if (x^2 + y^2 <= 0.25)
	hits = hits + 1
@printf("pi is approximately: %f\n",(4 * hits / numTimes))

You can see that the syntax is almost the same between the two languages. Julia requires end after if and for, but doesn’t require the : at the start of an indented block. Julia’s ranges are slightly different looking than Python’s ranges, with the range range(0,numTimes) written most naturally as 0:numTimes in Julia.

What about the timing, though?

Timing the Python version I get that:

pi is approximately:  3.1422708
real	0m7.817s

and for the Julia version:

pi is approximately: 3.141588
real	0m2.005s

So already Julia is obviously a bit faster, but the comparison becomes really obvious. For Python 100 million iterations gives us a program that runs in about 1m15s. For Julia, it took roughly 14s to finish.

Now, is that a definitive example that Julia is “5x faster than Python”? Absolutely not! It does, however, give us a strong hint that rewriting Python programs in Julia might make them run a lot more efficiently while still being very simple to write. As an additional caveat, while in a sense there’s no such thing as a fast language or a slow language, just a fast implementation or slow implementation, it does make a really big difference if the easy-to-use standard implementation for one language produces significantly more efficient code than the standard implementation of another language.

There’s one piece of syntax I haven’t explained yet, and it’s a really cool one! In the line @printf “pi is approximately: %f\n” (4 * hits / numTimes), the @ is used because printf isn’t an ordinary function but a macro!

Macros are an old, and sorely underused in my opinion, idea in programming languages. The idea of a macro is that it’s code that writes code. Macros take in code as arguments, transform the code, then spit back out the code that should actually run! Macros mostly exist in the lisp family of languages: scheme, common lisp, clojure, and the like. Julia has them too, though! In this case, @printf is a function that takes in a “formatting string” and generates really efficient code for inserting data into a string.

The great thing about languages having macro systems is that you can write your own control structures like if or for and still have them work like they were always a part of the language. So, for example, we can make a trinary if-statement that branches if its argument is positive, zero, or negative as:

macro tif(cond,pos,zer,neg)
	c = $cond
	if c > 0
	    return $pos
	elseif c == 0
	    return $zer
	    return $neg
@tif 2 println("greater than zero") println("equal to zero") println("less than zero)"

this program will correctly only print “greater than zero”, meanwhile if we’d written this as a function:

function tif(cond, pos, zer, neg)
    if cond > 0
	return pos
    elseif cond == 0
	return zer
	return neg
tif(2, println("greater than zero"), println("equal to zero"), println("less than zero"))

It prints out all three messages, which is absolutely the wrong behavior.

You can learn more about metaprogramming at the Julia page for metaprogramming: https://docs.julialang.org/en/stable/manual/metaprogramming/.

So we’ve talked a little bit about cool features of the language, but what are people using it for? Well, it has a really fast implementation, is easy to use, and has a ton of built-in libraries related to using matrices and vectors; that adds up to it being really popular for scientific computing. That means it’s really popular with people who are doing AI, data science, complex systems theory, and the like. So if the idea of doing science with computers sounds cool, Julia is definitely a language to check out.

Learn More

A profile from when Julia was first going public


A bare bones tutorial on Julia


A library for doing symbolic mathematics like algebra in Julia


An article comparing the performance of a fast Python implementation with the base Julia implementation


A “deep learning” library for Julia


The main Julia site