The last couple of days I have been working with the programming language Julia, designed for scientific computing. I have been rewriting the ruby code found in the book “Exploring Everyday Things with R and Ruby” to Julia. Being more used to languages like Ruby and Python it took a little time to get the hang of the Julia way of doing things. Specifically working with collections was different, so here I have made some notes about how to work most conveniently with Julia collections.

Working with Arrays

Make an array with one dimension:

julia> xs = [1,2,3,4] 4-element Array{Int64,1}: 1 2 3 4

Make a new array by squaring the members, using list comperhension:

julia> sqr_xs = [x^2 for x in xs] 4-element Array{Any,1}: 1 4 9 16

Note that we got an array of type Array{Any,1} . We know however that in this case, it could more accuratly be described as Array{Int64,1} . However the JIT compiler does not know that. This happens often in Julia. Then you can help it by adding a type assertion.

julia> sqr_xs = [(x::Int64)^2 for x::Int64 in xs] 4-element Array{Int64,1}: 1 4 9 16

A type assertion is not a casting, but more like both a hint and assertion that the type is what we say it is.

Since all the elements in a Julia array have the same type unlike Ruby or Python we can’t simply write [] to create an empty array. We have to specify the type:

julia> ys = Int64[] 0-element Array{Int64,1} # Add elements to ys julia> for x in xs push!(ys, x^2) end julia> ys 4-element Array{Int64,1}: 1 4 9 16 # Remove element from the back julia> pop!(ys) 16 # Remove from front julia> shift!(ys) 1 julia> ys 2-element Array{Int64,1}: 4 9 julia> empty!(ys) 0-element Array{None,1}

Removing elements

The function for removing elements from sets is the same as for splicing new elements into an array:

julia> xs = [5,4,3,2,1] 5-element Array{Int64,1}: 5 4 3 2 1 julia> splice!(xs,2) 4 julia> xs 4-element Array{Int64,1}: 5 3 2 1 julia> splice!(xs, 2:3, [11, 12]) 2-element Array{Int64,1}: 3 2 julia> xs 4-element Array{Int64,1}: 5 11 12 1

Working with Sets

You can create and add and remove elements to an empty set, much the same way as an array:

julia> s1 = Set{Int64}() Set{Int64}() julia> push!(s1,2) Set{Int64}(2)

However sets don’t have order like arrays, so the order in which you remove elements with e.g. pop! will be random.

julia> s2 = Set{Int64}(1,2,3,4) Set{Int64}(4,2,3,1) julia> pop!(s2) 4 julia> pop!(s2) 2

Of course with a set you can quickly remove specific elements:

julia> s2 = Set{Int64}(1,2,3,4) Set{Int64}(4,2,3,1) julia> delete!(s2,3) Set{Int64}(4,2,1)

Cheat Sheet

Empty array of type T

T[]

Empty set of type T

Set{T}()

Set with content of array xs

Set(xs...) Set{T}(xs...) # to assert elements are of type T

Modify collections

push!(collection, element) append!(collection, collection) pop!(collection) shift!(collection) delete!(set, element) splice!(array, index[, replacement])

Ruby to Julia

Here are some common patterns in Ruby and how the translate to Julia.

Ruby Julia xs.each {|x| for x in xs xs << x push!(xs, x) rand(N) rand(1:N) (1..10).step(2).each {|i for i in 1:2:10 10.times {|i| for i in 1:10 {"one" => 1, "two" => 2} {"one" => 1, "two" => 2}

Dealing with nil when there is no nil

Programming languages such as Python and Ruby will use nil a lot as markers. E.g. in this example we use nil to indicate that the facility as the restroom is empty (example from “Exploring Everyday Things with R and Ruby”).

class Facility def initialize @occupier = nil @duration = 0 end end

Unfortunatly there is not one single ready made solution to this in Julia. The best solution depends on the particular problem. One solution is this:

type Facility occupier::Union(Person, Nothing) duration::Int32 Facility() = new(nothing, 0) end

That is we create a Union type, meaning occupier can contain an object which is either of type Nothing or Person. Later you can do a “nil” check with:

is(occupier, nothing)

This might seem like there is no difference between this and nil . However the difference is that any field in Ruby or Python may get the nil value. But in Julia you have to explicitly allow a field to take nothing . Otherwise there is no way that field can hold nothing . If you try to assign nothing to a field of type Person you will get a type exception.

This has implications for how you structure your code, since you know that from a variable of type Person you never need to write checks for nothing to avoid getting a type exception thrown in your face. This is the sort of things that makes Java code riddled with null checks. You would only need to perform this check if the type is Union(Person, Nothing) .

Sometimes a better approach than Nothing is to use Null objects. People already do this in Java, C++ etc. That basically means creating one instance of a type which you designate as the Null object. It has its fields set in such a way that you can check whether it is the Null object or you simply compare identity.

An example how you can do this: