Taking a complete look at creating complex constructors with Julia.

(Image by author)

Introduction

Constructors are a computer programming tool that allows datatypes to be condensed down into easy-to-understand containers that can effectively be used as variables with methods to create some pretty amazing results. In the Julia language, however, constructors are an entire beast of their own — and are more complex than one might imagine upon first glance. Types in Julia can be handled in a multitude of ways, they can go from completely functional with types that the compiler is well-aware of and are completely immutable to object-oriented with types that are delivered to the compiler right when they are made — which is part of the charm of the language.

There are two different types of constructors in the Julia programming language:

  • Inner Constructors
  • Outer Constructors

Both of these constructors have their own specific purpose and are both presented to return the same type ultimately. However, we can use outer constructors to support arithmetic and type-processing for different types with dispatch.

Outer Constructors

Outer constructors are the typical type of constructors that programmers are going to work with in Julia. That being said, this is often the tip of the iceberg and more of cover-up for the ultimate programming interface. That being said, you can create an outer constructor by using the struct keyword. Meet my new friend, Hal the Janitor:

abstract type Employee end
struct Janitor <: Employee
wage
age
years
end
Hal = Janitor(25, 63, 2)

We have just created an outer constructor for our new type, Janitor. You might be familiar with these sort of constructors, however, let’s say that we didn’t know what age Hal was without querying a data-base, however, we do have a list of UUIDs for each employee? This application would quickly fall apart with a function that needs to be called to replace the type. This is exactly the purpose of an inner constructor.

Inner Constructors

Inner constructors can be used to make types that don’t necessarily need to be containers for data that is supplied by the user, but instead your function. While in most functional programming language this would mean creating a completely separate function far away from this constructor, in Julia the two constructors can work with each other and have the compiler ready for a return of the type that the inner constructor is working with, check it out:

abstract type Employee end
struct Janitor <: Employee
wage::Float64
age::Int64
years::Int64
    function Janitor(uuid::Int64)
    wage, age, years = query_db(uuid)
    return new(wage, age, years)
end

Now if we call Janitor with a float and two integers, like so:

Hal = Janitor(8.25, 5, 1)

We still get the same return as before. However, we can also call it with a single integer, which will run our inner constructor and use the logic with the UUID!

Hal = Janitor(hals_UUID)

This will, of course, return a type of Janitor with the information that we provided, and we can add a lot of type casting on top of it to optimize this code and make it far more efficient than it would be otherwise. This is especially true for making outer constructors with an entirely separate method!

We can take this a step further by using dispatch with the appropriate types in more than one way. For example, we can use dispatch inside of the inner constructor to create more functionality for datatypes that can be passed for the return. Another great thing we can still do using this method is utilize Julia’s type-hierarchy system. This system is akin to something like a sub-class system in something like Python.

Although Julia is a relatively basic functional programming language at its core, it is that simplicity that also helps it to implement such ground-breaking features. For me at least, this concept was very breathe-taking, because not only can we work with dispatch in a global scope with functional method calls, but it can also be utilized in every possible way in typing using multiple constructors together to get the job done!

Conclusion

Constructors are a necessary and important programming concept in general. However, what constructors are capable of in the Julia programming language is actually astounding. Not only can they be used to create mutable and immutable types, but also utilize initialization function. If this look at constructors was entertaining, you might also enjoy another article where I use this same concept to work with object-oriented programming in Julia!:

How To Turn Julia Into Python!

Thank you for reading, it means a lot to me!


An Advanced Look At Constructors In Julia was originally published in Towards Data Science on Medium, where people are continuing the conversation by highlighting and responding to this story.