First, we'll create a composite type for coordinates. The constructor takes the same name as the type name, and can do things like perform validation on instantiation.
In [17]:
type CoordinatePair
lon::Float64
lat::Float64
function CoordinatePair(lon, lat)
if lon < -180 || lon > 180
error("Longitude must be >= -180 and <= 180")
end
if lat < -90 || lat > 90
error("Latitude must be >= -180 and <= 180")
end
new(lon, lat)
end
end
Let's test our new type validation method.
In [18]:
CoordinatePair(200, 35.34)
In [19]:
latlon = CoordinatePair(-75.343, 39.0343)
Out[19]:
Once the type is defined, you can access the subtypes using dot notation.
In [20]:
latlon.lat
Out[20]:
Construction of array literals look as you would expect. Julia indexing starts at 1.
In [5]:
latlons = [(-75.111, 39.111), (-75.222, 39.222), (-75.333, 39.333)]
latlons
latlons[1]
Out[5]:
Creating lambda functions is done with ->
In [21]:
map(c -> CoordinatePair(c[1], c[2]), latlons)
Out[21]:
You can also provide a do block to functions, which is helpful for long or complex lambdas
In [39]:
coords = map(latlons) do c
# If we had some conditions or more
# complex math to do, it would be
# handy to put it in here rather than
# cram it on one line.
Coordinates(c[1], c[2])
end
Out[39]:
If we try to add two of Coordinates, we'll get an error because there's no version of the + function that matches our type signature
In [40]:
+(coords[1], coords[2])
Out[40]:
Julia uses multiple dispatching to find a version of a function that matches the passed type(s). Let's create a version of + that supports Coordinates
In [42]:
function +(a::CoordinatePair, b::CoordinatePair)
diff_lat = a.lat + b.lat
diff_lon = a.lon + b.lat
CoordinatePair(diff_lon, diff_lat)
end
Out[42]:
In [43]:
+(coords[1], coords[2])
Out[43]:
Julia supports unpacking of lists
In [3]:
lat, lon = [-75.434, 39.231]
lon
Out[3]: