Many people discussing Julia look to its claims relating to speed (vs. languages such as Python), and that is an important feature of a language built for crunching numbers. Some people like to harp on the OO characteristics of a language, or it functional abilities, but it is the basic language structures, that make or break a language. It is easy to write programs in Julia. Part of this ease comes with a usable syntax, whilst other parts are attributable to the lack of low-level features, at least from the perspective of the novice user. Below we will discuss some of the more interesting features of Julia.
One of the things I like, yet may make other people cringe, is the simplistic nature of some mathematical expressions. In math, an expression may be of the form x = 4a + b2. In C this would be written as:
x = 4 * a + b * b
But in Julia, it can be written as:
x = 4a + b^2
There are features of Julia that making writing expressions easier. For example, Julia is capable of directly evaluating a conditional expression such as 1<x<12, which in C would require an expression of the form: ((x>1) && (x<12)). Swapping the values stored in variables is also easy, using an expression of the form: a, b = b, a.
Some of the more interesting features of Julia include allowing variable names to use Unicode (UTF-8), so either the word “pi”, or π can be used. However it is also possible to use traditional numeric comparison operator, ≠ instead of !=, ≤ instead of <= etc. The only problem here might be the lack of practicality, i.e. keyboards, and might require some form of IDE to make usable.
Julia also does some interesting things with operators. Unlike C which overloads the division operator, Julia instead opts to use the function div(x,y), and replaces the % C uses for modulus with the function mod(x,y). It also introduces rem(x,y) to calculate the remainder. Types are consistent, meaning that Int8 implies an 8-bit integer, and Int64 a 64-bit integer. Unsigned integers are defined by prefixing with a U, e.g. UInt8. Floats are defined in a similar manner.
Control structures are similar to those found in other languages, however they do benefit from a usability standpoint. Julia essentially offers one conditional statement: if-elseif-else, there is no switch or equivalent. The if statement does not require the use of ( ) to delimit the conditional expression (but you can use parentheses if you like). There is also no ambiguity caused by the dangling else, such as in C, as all control structures are terminated with the end clause. Some people may see the addition of a control-structure terminator such as end adding verbosity to the language, but in reality it adds more clarity than anything else. Unlike C and Python, Julia also does not allow anything except a boolean evaluation in the conditional (so expressions like x = y are avoided).
There is no switch or similar statement in Julia, maybe because it offers no additional functionality over the if structure. The switch statement is one of the few which has to be very well designed, otherwise it can end up doing more harm than good. A switch statement would be a welcome addition to the language, but only if similar to that incorporated in Swift, rather than the ineffectual design of C.
From the perspective of loops, Julia provides only two: for and while. The while loop is similar to that found in other languages. The for loop, uses a much simpler syntax:
for i = 1:100 ... end
The for loop can also iterate over containers, using the keyword in.
for i in [1,1,2,3,5,8] ... end
The keywords break and continue exhibit the same behavior as in C. As an interesting side, Julia allows multiple nested loops to be combined into a single outer loop, forming a “cartesian product of iterables”.
for i=1:100, j=1:100 ... end
Like its contemporaries (e.g. Swift), there is also no goto statement. Considering how ubiquitous exception handling is in Julia, I would argue that it is hardly needed. The exception handling is itself very much akin to that found in Ada. Here are a couple of examples:
BoundsError - array out of bounds DomainError - sqrt(-1)
Julia also allows the programmer to define their own exceptions, offers warnings and informational messages that do not interrupt execution, and try/catch combinations to allow exceptions to be tested. This stops any of the problems confronted by novice programmers using languages such as C.
Functions are easy to create.
Julia uses a single function format, there is no differentiation between functions that return values and those that don’t. Functions are identified using the keyword function, as opposed to def from Python, or nothing like C/C++. There is no need to specify a return type, or use the keyword void. The value returned is the value of the last expression in the body of the function, or alternatively that associated with the traditional keyword return. Functions can return multiple values in the guise of tuples, as well as mutable values. Julia also allows for an arbitrary number of arguments, and optional arguments (with a default value).
Unlike other languages such as C, Julia performs argument passing by “pass-by-sharing”, which means that values are not copied when they are passed to functions. Generally the arguments given to the function are not modified, except mutable values such as arrays (akin to pass-by-reference). This means there is no need for the novice programmer to worry about the difference between the different modes of passing parameters to a function. Unlike C, there is also no need to learn about pointers in order to use functions. Julia also provides libraries in the guise of a module.