Julia: Looks like Python, feels like Lisp, runs like Fortran. The syntax is minimalist and is based on English keywords. Therefore Julia is very readable compared to C++ and Java languages. You can learn Julia to proficient level in less then one week as your first computer language.

Julia Video Tutorial ~ 1:40

Julia Features

What makes Julia the language that deserve popularity? Why one will chose Julia over Python, Swing or Go. Here we present the most appreciated features. These features makes programming with Julia productive and rewarding. These features makes Julia code is easy to read and understand. I have started with the most valuable on top.

PerformanceApproaching that of statically-compiled languages like C and Fortran
Co-routinesLightweight  threading designed for parallelism  and distributed computation
Multiple dispatchAbility to define function behavior across many combinations of argument types
Dynamic type systemDefine advanced types for documentation, optimization, and dispatch
User-defined typesThese types are as fast and compact as built-in types
Type inferenceType is created determined automatically from literals
Meta-programmingLisp-like macros and other meta-programming facilities
Call PythonCan be used to call python functions using PyCall package
Call C functionsDirect C call with no wrappers or special APIs
InterpreterPowerful shell-like capabilities for managing other processes
Unicode StringsEfficient support for Unicode including but not limited to UTF-8
Unicode OperatorsWe can use Unicode symbols as operators
Julia hoistingThe ability to use a type or a function before it is defined

Julia execution

Julia implements LLVM-based just-in-time (JIT) compiler. Combined with the language’s design allow it to approach and often match the performance of C. That means we have a dynamic language, that uses native computer types to create a fast and optimized program fro different platforms. Brilliant !!!

Julia syntax

Julia language has a very polished syntax. It eliminate annoying elements found in  other languages while implementing most of the important features. Having a simplified syntax matter. This is one of the simplistic language out there that have significant performance and power. This is one of the reason we recommend Julia to beginners.
  • Full English names for keywords;
  • Optional “;” at the end of statement;
  • Long expressions can span multiple lines;
  • Block of code is terminated using “end”;
  • Type inference makes declarations unnecessary;
  • The indentation and the end of line are irrelevant;
  • Julia has support Unicode operators like:  ≤ ≥ ≠;
  • Strings are enclosed in double quotes “string”;
  • Julia operators are functions;

Example of program:
print("Hello World")

Julia Comments

A line comment is starting with symbol “#” exactly like in Python. To create a multi-line comment in Julia we use two symbols: #= …. =#. That is unconventional but has a logic behind. We can create a separator line like this: #================================#. Nested comments are possible in Julia.

Julia Variables

When you wish to declare a variable in Julia you use Duck typing. For this you use a type literal to provide enough information to the compiler to derive the type. Once the type is established you can use the variable in expressions. In Julia evening is an expression.

message = "Hello World"

The message is a string variable having value “Hello World”. Observe that we do not use keyword “var” like in JavaScript or other languages.  Also in Julia a variable can be re-purpose. The type can be changed when the variable is assigned using “=” symbol. A new value of a different type can be assigned.

Julia Constants

In Julia we use global constants to improve performance and protect them against change. So the constant values are declared using keyword constant to make the program faster. In local scope the constant is not faster than a simple variable.

# Julia example
  constant pi = 3.14

Numeric type

Julia uses native numeric types. This is one of the key elements to make fast Julia programs. When we assign a variable the type is automatically assigned using an assumption. If we wish to assign a specific type to a variable we use a “type annotation” this start with “::” symbol.

  • Integer types: Int32, Int64
  • Floating-point types: Float32, Float64

To write a floating point number we use dot (.) after the number or before the number if the number is <0.

# Float variables
  v = 5. 
  x = .05
  y = 5.05

# Integer variables
  i = 2  #use default Int64 type   
  z::Int8 = 10 #use type annotation

Boolean type

Boolean is a native type having two values: false < true. Boolean variables can be used to create conditions. To create a Boolean variable we can use assign operator with a literal “true” or literal “false”, or we can use a logical expression to assign the result to a variable. In next example we use Boolean operators: && for “and”, || for “or” and ! for “not”. These are the basic operators for Boolean algebra.

# Boolean variables
  locked = false
  closed = true
  is_secure = closed && locked
  not_secure = !closed || !locked

Array type

In Julia array represents a collection of elements all having the same type. This collection is indexed starting with index 1 until the last element end. We use square brackets [ … ] and elements are separated by comma or semicolon.

# One array of with no elements is represented like this
a = []

# 1-dimensional array literals can be written with comma-separated values.
b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
b[1]   # this is 4
b[end] # this is 6

# 2-dimensional arrays use space-separated values and semicolon-separated rows.
matrix = [1 2; 3 4] # this is 2x2 Int64 Array

Tuple type

Tuples are immutable collection of elements. We use notation (,) to create tuples. The tuple collection is indexed.

tup = (1, 2, 3) 
tup[1] # this is 1

Dictionary type

A dictionary is a collection of pairs. Each pair is (key, value).

# Dictionaries store mappings
empty_dict = Dict()

# You can create a dictionary using a literal
filled_dict = Dict("one"=> 1, "two"=> 2, "three"=> 3)

Julia Functions

We declare a function in Julia using keyword [function]. We end the function using simple keyword “end”. In other languages like Level 123 we use: “end function”. Therefore Julia is more like Pascal. In Ada and PL/SQL we use “end <function_name>”.  In Python we do not use “end” but we reduce indentation level. So what you think is best?

Example:

# In this function we use $ symbol like in Perl
function say_hello(name)
  println("Hi $name, it's great to see you!")
end

As you can see in the previous example we do not use any symbol after parameter list. In Python and Level 123 we use “:”. In Ada and PL/SQL we use “is”. But Julia simplify the syntax to minimum. Also this function do not return any result but has a side-effect.

To execute a function we use function name followed by (). For example we can cal “say_hello” function using notation: say_hello("Julia") This function will print to console “Hi Julia, it’s great to see you!” the $name place-holder is replaced by “Julia” value.

The return

The last expression value in a function is the result of the function. So easy to use and elegant no? What if the things are more complex. Can we create multiple exit points? Yes we can using the return keyword. This will skip all other statements and create an exit point before the end. We can use many return statements.

Example:

# In this function we calculate a math x operator y 
function math(x, y, operator)
  if operator=="+" 
    return x + y
  elseif operator=="*" 
    return x * y
  elseif operator=="/" 
    return x / y
  else
    return 0
  end
end

The decision

In the previous example we show a “if” statement also known as conditional statement.  Easy to to use and simplified syntax. Julia do not use “then” keyword or “:” symbol after the condition like in other languages. Again Julia show an elegant and simple approach. It is used for one condition or multiple conditions using “elseif” compound keyword. In python this keyword is “elsif”.

Synax:

# This is the if-elseif-else-end statement 
  if [first-condition]
    [furst-true block]
  elseif [second-condition]
    [second-true block]
  ...
  else
    [fasle-block - no condition is true]
  end

The if statement can have many condition and for each condition a block of code. The else statement is the alternative (optional) block that is executed when no condition is true. For each block we can also have nested if statements. This is somesing we wish to avoid if possible. It’s a good practice to not get too far from left side.

While loop

While statement is used to repeat a block of code multiple times as long as one condition is true. If the condition is always true then we have an infinite loop. We can use a control variable that we increment inside the loop. In the next example we also learn two operators:  “<=” and “+=” to check the value of the control variable “i”. After the loop this control variable is available.

# next program will print:  1,2,3,4,5,done
i=1
while i <= 5
   print(i)
   print(",")
   i += 1
end
print("done")

For loop

This is a repetitive statement that execute a finite number of times using a control variable.  Next example is more compact:

# next program will print:  1,2,3,4,5,done
for i = 1:5
   print(i)
   print(",")
end
print("done")

Loop control

We can early terminate a loop by using break. We can also skip execution of statements and jump back to beginning using  continue keyword. Unlike while loop the control variable “i” is local inside the for loop and not available after the loop is ending.

# next program will print: 3 6 9 one per line
for i = 1:10
   if i % 3 != 0
     continue
   end
   println(i)
end

Modules

Julia is modular. A module is like a package that encapsulate several members. A module can import other modules and can export members. One module is stored in one or many files. One file can contain one or more modules. So the module is a supra-structure used to group together members. Each member exported or not.

Syntax:

module <module_name>

[import <module>]
...
[export <members>]
...
[declare_members]
...
end

In the previous example a module can have two optional keywords: import and export. The module is using hoisting technique. We can export a member before we declare the member. So the export is above the declaration region. Julia has 3 standard modules that we do not have to import: Main, Core, and Base.

When we import a module all it’s export members can be used directly in the global namespace of the module. The private members of the module can be used with dot “.” punctuation: ModuleName.member_name. Remember the module name is usually with capital letters. Member name is usually lower-case except types that start with upper-case letter.

Variable Scope

A variable can have a global scope or local scope. A variable that is defined outside of any function is a global variable. A local scope is defined for every function. If the functions are nested, the local function can see the variables in the parent scope. Also a function can have internal loops and other blocks that can have a nested soft local scope.

We can force local scope or global scope variables using keyword: “local” or “global” similar to Python. So in the next example the x is local and the y is global inside the function fix.

#In next example x is not modified but y is
x = 0
y = 0
function fix() 
   local x
   x = 12

   global y
   y = 12 
end
println(x)
println(y)

# will display:
0
12

Note: Julia is using hoisting technique. That means the location of declaration: local or global has no importance.

Julia Exceptions

When something goes wrong the execution of the program can be stopped. This is called an exception. We can create exceptions on purpose to show to the user that something has gone wrong and we can print a message to explain the situation. In Julia there are pre-define exceptions that have a name and are automatically created by the system in certain situations.

We have two situations. One is when we wish to “catch” the exception and continue the program. Another is we wish to execute something important before the program stop execution. We use a try block with two keywords: catch and finally. We can use both clauses or only one depending on the case.

# try block syntax
try
  [executable_region]
catch
  [exception_handler]
finally
  [something_important]
end

Example:

f = open("file")
try
    # operate on file
finally
    close(f)
end

Example:

x = 0
try
    z= y/x
catch err
    if isa(err, ZeroDivide)
       println("error division by zero")
    end
end

In the previous example we catch the error and copy the error in variable err. Then we use function isa() to analyze the error type. We can create errors using error() function and throw() function. Most of the type we do not catch errors and we do not create error handlers in programs.

Arithmetic Operators

The following arithmetic operators are supported on all primitive numeric types:

ExpressionNameDescription
+xunary plusthe identity operation
-xunary minusmaps values to their additive inverses
x + ybinary plusperforms addition
x – ybinary minusperforms subtraction
x * ytimesperforms multiplication
x / ydivideperforms division
x \ yinverse divideequivalent to y / x
x ^ ypowerraises x to the y power
x % yremainderequivalent to rem(x,y)

Bitwise operators

These operators are performing fast low-level operations on bits on native integer types.

ExpressionName
~xbitwise not
x & ybitwise and
x | ybitwise or
x $ ybitwise xor exclusive or: (deprecated)
x >>> ylogical shift right
x >> yarithmetic shift right
x << ylogical/arithmetic shift left

Updating operators

Every binary arithmetic and bitwise operator also has an updating version that assigns the result of the operation back into its left operand. The updating version of the binary operator is formed by placing equal symbol “=” immediately after the operator like this:

+=, -=, *=, /=, ^=, %=, ~=, &=, $=, >>=, <<=

Note: The update operator is not in-place. What it means is the variable on the left side can change its type. So these operators are actually version of assign operator.

x *= 2  #is equivalent to x = x * 2

Numeric comparison

A numeric comparison can be used into a conditional expression. It has a result of type Boolean that is true or false.

OperatorName
==equality
!=, ≠inequality (disjunctive)
<less than
<=, ≤less than or equal to
>greater than
>=, ≥greater than or equal to

Logical operators

Logical operators and comparison operators can be combined to create logical expressions that evaluate to true or false.

OperatorName
&&AND
||OR
!NOT

The Boolean table of truth

In Julia Boolean values are: true, false. We cant use 1 and 0 like in other languages. Next is a combination of possible values for A, B and the result of several basic expressions. A&&B meaning A and B, A||B meaning A or B then !A meaning negation of A an then !B meaning negation of B. If you are not familiar with these expressions then you need to look into Boolean algebra.

ABA&&BA||B!A!B
falsefalsefalsefalsetruetrue
falsetruefalsetruetrue0
truefalsefalsetruefalsetrue
truetruetruetruefalsefalse

Punctuation

In the next table we present a mingle of symbols used by Julia for different purposes. Some are operators but some are just conventions.

symbolmeaning
@minvoke macro m; followed by space-separated expressions
!prefix “not” operator
a!( )at the end of a function name, ! indicates that a function modifies its argument(s)
#begin single line comment
#=begin multi-line comment (these are nestable)
=#end multi-line comment
$string and expression interpolation
%remainder operator
^exponent operator
&bitwise and
&&short-circuiting Boolean “and”
|bitwise or
||short-circuiting Boolean “or”
bitwise xor operator (use to be $ but I think it was changed)
*number multiplication, matrix multiplication, string concatenation
()the empty tuple
~bitwise “not” operator
\backslash operator
complex transpose operator Aᴴ
a[]array indexing
[,]vertical concatenation
[;]also vertical concatenation
[   ]with space-separated expressions, horizontal concatenation
T{ }parametric type instantiation
;statement separator
,separate function arguments or tuple components
?3-argument conditional operator (conditional ? if_true : if_false)
“”delimit string literals
delimit character literals
` `delimit external process (command) specifications
splice arguments into a function call or declare a varargs function or type
.access named fields in objects/modules, also prefixes elementwise operator/function calls
a:brange a, a+1, a+2, …, b
a:s:brange a, a+s, a+2s, …, b
:index an entire dimension (1:end)
::type annotation, depending on context
: ( )quoted expression
:asymbol a
<:sub-type operator
>:supertype operator (reverse of subtype operator)
===egal comparison operator

Keywords

Next I will list several Julia keywords in logical order but not all of them. You may encounter other keywords in practice. I will try to add more keywords here when I fully understand them. Remember this article is just an introduction tutorial not a reference document.

#KeywordDescription
trueThe constant true is a Boolean value
falseThe constant false is a Boolean value
maybeNot a keyword 🙂 just teasing you
constantDefine a constant usually a global
globalUsed in local scope to show that a variable is not local
localUsed in local scope to force a variable to be local and hide a global variable
beginMark the beginning of a compound expression block “begin … end”
letMark the beginning of a let block: “let … end”
endMark the end of a block, function or module
 function Create a function
moduleCreate a module
returnCreate an exit point from a function and return a result
importImport into a module public members from another module
exportExport module public members to be imported into another module
ifDecision statement
elseAlternative block for false condition
elseifAlternative block for second condition
whileStart a while loop  “while … end”
forStart a for loop: “for … in … end”
inUsed with for to iterate over a range or collection
breakStop a while or a for loop
continueShortcut a loop and continue with next iteration
printPrint a message to console
printlnPrint a message to console and add end of line
tryStart a block of code that may rise exceptions
catchStart exception handling block
finallyIs the final part that execute not matter what for a try block
throw()This is a standard function to create an exception
error()Also create an exception of type ErrorException
abstractDefine an abstract type
primitiveUsed to create a primitive type
typeUsed with abstract or primitive keyword to create a type
structCreate a structure like a record (immutable)
mutableUsed with struct to create a mutable struct
unionUsed to create a union type
typeof()This is a function used to display type information about a variable
isa()A function that return true or false about type of a variable
supertype()Extract the supe-type information for a type
Nullable{}Create a null-able type
isnull()Check if a null-able type is null
macroblock of code execute when code is parsed (used to generate code), invoke macro with @ operator.
quoteexpression that span multiple lines used as alternative to quote operator “:”
eval()used in meta-programming to evaluate a string expression