Programming in JuliaCustom types
Suppose you want to write a program which keeps track of the albums you own. Each album is associated with several data, like the name of the album, the year it came out, the number of tracks, etc. You could store all these data by assigning them to different variables, but that becomes untidy very quickly. For example, you will frequently want to pass an album to a function, and you don't want that function to require a long list of parameters just because the album has a lot of data associated with it.
What you want is to be able to treat each album as its own Julia object, with all its associated data stored inside. In other words, you want an
Album type. You can do that with the
struct Album name artist year duration end A = Album("Abbey Road", "The Beatles", 1969, "47:23")
In the last line, we have defined a new object of type
Album and saved it to the variable
A. We call
duration fields of the
Album type. The fields of an object can be accessed by name using dot syntax:
We can define functions to operate on our new data type. For example, we might want to be able to calculate how old an album was as of a given year. We can specify types for a function's arguments using double colon syntax:
function num_years_ago(A::Album, year::Integer) year - A.year end
Integer is an abstract type which encompasses
Int32 (which uses 32 bits instead of 64), and any other type which represents a mathematical integer.
One reason it's helpful to be able to specify type information when defining a function is that we can specify different behavior for different types:
function num_years_ago(earlier_year::Integer, later_year::Integer) later_year - earlier_year end num_years_ago(A, 2019) # returns 50 num_years_ago(1986, 2019) # returns 33
We say that
num_years_ago now has two methods: one which accepts an
Album as its first argument and an
Integer as its second argument, and one which accepts
Integers for both arguments. Julia is responsible for correctly dispatching each function call to the correct method. This feature of Julia is called multiple dispatch.
Write a type
Line for representing non-vertical lines in the plane. Write a two-argument method
intersect which finds the intersection point of two lines (you may return the intersection point as a tuple of floats, and for simplicity, you can assume the lines intersect).
Solution. Since we only need to store non-vertical lines, we can represent every line via its slope and intercept. We can specify that these data types should be
Float64s if we want:
struct Line slope::Float64 intercept::Float64 end
The intersection point of two lines is given by
function intersect(L::Line,M::Line) x = -(L.intercept-M.intercept)/(L.slope-M.slope) y = L.intercept + x*L.slope (x,y) end