Wiki: Julia

Check CGSE Julia golfing tips

imperative/functional/array

Julia syntax is flexible enough to allow different programming styles. A simple task as printing the numbers from 1 to 10 each on a new line can be written in several ways.

The classic imperative style reads

# 29 bytes
for i=1:10
    println(i)
end

This can be easily golfed by removing all the indentation

# 24 bytes
for i=1:10;println(i)end

Note that no space is required between the closing bracket and end.

Julia supports list comprehension as well, therefore we may write also

# 23 bytes
[println(i) for i=1:10]

A more functional approach would use map as

# 23 bytes
map(i->println(i),1:10)

where -> is used to define an anonymous function. The previous can be even shorter:

# 20 bytes
map(println,1:10)

However, julia really shines when we start broadcasting functions over arrays. Every function can be applied to all the elements of an array by postpending a ., hence

# 14 bytes
println.(1:10)

Broadcasting

You can use the broadcast operator + pipe operator to save parentheses. (x->x^2+1).([1,2,3]) => [1,2,3].|>x->x^2+1

Comparison chaining

Julia supports comparison chaining like Python, so this also means you can sometimes save a character by replacing && with or similar:

x>0&&println(x) # 15 chars, 15 bytes
x>0≠println(x) # 14 chars, 16 bytes

Symbols instead of string literals

Using a symbol instead of a string literal can save one byte:

println("FizzBuzz")
println(:FizzBuzz)

Case study

Here is a weird program to demonstrate julia's strangest features.

n<* =0n,10>n+1<*
1<println

What's going on? Even though we redefined *, julia will still understand 0n as 0*n. Julia can use symbols as arguments when defining a function. We need a space between * and =. The symbol ~ is usually more useful, since no space is required after ~.

Renaming * to p:

n<p=p(0,n),10>n+1<p
1<println

Next we can rewrite that chained comparison as 10>n+1 && n+1<p, and rename < to f. Even though we have redefined <, the rules of comparison chains still apply!

f(n,p)=p(0,n),10>n && f(n+1,p)
f(1,println)

So, the initial program defines a recursive function, which we use to iterate from 1 to 9, printing each number with a leading 0. Redefining a comparison operator in this fashion is often the shortest way to iterate in julia. Additionally passing auxiliary functions as symbols can save bytes in many situations.