Day 6: Composite Types

I’ve had a look at the basic data types available in Julia as well as how these can be stashed in collections. What about customised-composite-DIY-build-your-own style types?

Composite types are declared with the type keyword. To illustrate we’ll declare a type for storing geographic locations, with attributes for latitude, longitude and altitude. The type immediately has two methods: a default constructor and a constructor specialised for arguments with data types corresponding to those of the type’s attributes. More information on constructors can be found in the documentation.

julia> type GeographicLocation
julia> methods(GeographicLocation)
# 2 methods for generic function "GeographicLocation":

Creating instances of this new type is simply a matter of calling the constructor. The second instance below clones the type of the first instance. I don’t believe I’ve seen that being done with another language. (That’s not to say that it’s not possible elsewhere! I just haven’t seen it.)

julia> g1 = GeographicLocation(-30, 30, 15)
julia> typeof(g1) # Interrogate type
GeographicLocation (constructor with 3 methods)
julia> g2 = typeof(g1)(5, 25, 165) # Create another object of the same type.

We can list, access and modify instance attributes.

julia> names(g1)
3-element Array{Symbol,1}:
julia> g1.latitude
julia> g1.longitude
julia> g1.latitude = -25 # Attributes are mutable

Additional “outer” constructors can provide alternative ways to instantiate the type.

julia> GeographicLocation(lat::Real, lon::Real) = GeographicLocation(lat, lon, 0)
GeographicLocation (constructor with 3 methods)
julia> g3 = GeographicLocation(-30, 30)

Of course, we can have collections of composite types. In fact, these composite types have essentially all of the rights and privileges of the built in types.

julia> locations = [g1, g2, g3]
3-element Array{GeographicLocation,1}:

The GeographicLocation type declared above is a “concrete” type because it has attributes and can be instantiated. You cannot derive subtypes from a concrete type. You can, however, declare an abstract type which acts as a place holder in the type hierarchy. As opposed to concrete types, an abstract type cannot be instantiated but it can have subtypes.

julia> abstract Mammal
julia> type Cow <: Mammal
julia> Mammal() # You can't instantiate an abstract type!
ERROR: type cannot be constructed
julia> Cow()

The immutable keyword will create a type where the attributes cannot be modified after instantiation.

Additional ramblings and examples of composite types can be found on github. Also I’ve just received an advance copy of Julia in Action by Chris von Csefalvay which I’ll be reviewing over the next week or so.