This is the fourth part in the article series – **‘Getting started with Julia language’. **If you have ever attempted to write an application, then you would have come across Julia multiple times before. Julia is a high-level, high-performance, dynamic programming language. It is an ideal choice for programs that require numerical computations, such as, ML/AI. In this article, we’ll take a look at the literals and operators that we find in Julia language. In the previous artickes, we’ve already covered how to set up Julia, Julia REPL and packages and Julia variables and types.

Literals are means of expressing specific values in a program.

We’ve already come across the string literals in some examples, String literals can be created by enclosing the value between ” (double quotes).

`string_val = "test string"`

Note: In Julia, strings can only be defined between ” (double quote), while ‘(single quote) is used for defining a character.

`char_val = 'a'`

- Array literals are N-dimensional mutable containers.
- Each element they contain has to be either a variable or otherwise a valid literal.
- Can be heterogeneous, i.e, values don’t have to be of the same typ
- Values are separated by a , (comma)
- Values can be updated by subscripting through their index.

Note: Compared to other programming languages, Julia uses 1 indexing rather than 0 indexing, i.e, indexes start at 1 instead of 0.

**1-D arrays** — A linear array which has only one subscript,

# Initialize an array with values arr1 = [1, 2, "sausage", 5.9] # Initialize an empty array arr2 = [] # Update value by index arr1[1] = 3 # Updates 1st element of arr1

**Multidimensional arrays** — A rectangular array of numbers or symbols arranged in rows and columns, also known as matrix. A matrix can be declared in 2 ways,

mat1 = [[1,2,3] [4,5,6] [7,8,9]] --or-- mat2 = [1 2 3; 4 5 6; 7 8 9] # Update 2nd column in 1st row mat1[1][2] = 5

While creating a multidimensional array, each row has to be of the same length, otherwise, it raises an error.

Elements of bidimensional arrays can be accessed with the array[row,col] or array[row][col] syntax.

**Nested arrays **— Simply speaking, these are an array of arrays, i.e, a 1-D array with vector values.

arr2 = [[1,2,3], [4,5,6], [7,8,9]]

This creates a 1-D array with 3 elements (each of which are vectors). Note the , separation between each vector elements.

Tuples are similar to 1-D arrays, but unlike them, tuples are immutable.

`tuple1 = (1, 4, 5.5, "test")`

NamedTuples are collections of items whose position in the collection (index) can be identified not only by the position but also by name.

namedtuple1 = (a=1, b=2, c=3) # Accessing elements by name namdetuple1.a namedtuple1.c

Dictionaries are used to store key-value pairs.

# Initialize a dictionary with values dict1 = Dict('a'=>1, 'b'=>2, 'c'=>3) # Initialize an empty dictionary dict2 = Dict() # Add new pairs to dictionary dict1['d'] = 4 dict2['e'] = 5 # Update existing pairs dict['a'] = 8

They may seem similar to NamedTuples but both have some major differences,

Dictionaries are mutable while NamedTuples are immutable

Dictionaries are type unstable if different type of values are stored, while NamedTuples remain type-stable

d = Dict(k1=>"v1", k2=>2) # Dict{Symbol,Any} nt = (k1="v1", k2=2,) # NamedTuple{(:k1, :k2),Tuple{String,Int64}}

Sets are unordered collections used to store unique values.

# Create an empty set set1 = Set([]) # Create a set with values set2 = Set([1, 2, 3])

Though duplicate entries are present at the time of set construction, the resulting set will only have unique values

set3 = Set(["abcd", "efg", "efg", "hijk"]) Output -> Set(["hijk", "efg", "abcd"])

A range in Julia is simply a shorthand for a sequence of numbers that are all spaced equally.

Syntax:

`range(start:[step]:end)`

- start — denotes the start value of the range
- step — is optional, specifies the spacing between each values in the sequence
- end — denotes the end value of the range

Ranges are lazy, meaning the values are not immediately available until they are needed. However, the generation of the values can be forced by using the collect() function.

0:20 # This return UnitRange{Int64} collect(0:2:20) # This will generate a 6-element Array{Int64,1} collect(0.5:5.5) # This will generate a 6-element Array{Float64,1}

Sometimes, it’s useful to have a single alias for multiple types. To do so, we can create a type union using the constructor Union:

Numeric = Union{Int, Float64} # Assert for Int 5::Numeric # Returns 5 # Assert for Float 7.06::Numeric # Returns 7.06 # Assert for string "abcd"::Numeric # Results in TypeError

As you can see from the above example, since String type is not in the Union Numeric , asserting a string will raise TypeError.

There are several operators in Julia, which include Arithmetic, Bitwise, Logical, Assignment, Vectorized dot and Relational.

**Arithmetic Operators**

Arithmetic operators are used to perform arithmetic operations such as addition, subtraction, multiplication, division, etc.

Operator | Description | Syntax |
---|---|---|

+ | Plus: Adds two operands | x + y |

- | Minus: Subtracts two operands | x - y |

* | Multiplication: Multiplies two operands | x * y |

/ | Division: Divides the 1st operand by 2nd | x / y |

^ | Power: Raises x to the yth power | x ^ y |

% | Modulus: Returns the remainder of a division | x % y |

**Bitwise Operators**

Bitwise operators are for bit level programming in which individual bits of an integer expression is manipulated.

Operator | Description | Syntax |
---|---|---|

~ | Bitwise NOT | ~x |

& | Bitwise AND | x & y |

| | Bitwise OR | x | y |

⊻ | Bitwise XOR | x ⊻ y |

>>> | Logical right shift | x >>> y |

>> | Bitwise right shift | x >> y |

<< | Bitwise/Logical left shift | x << y |

**Logical Operators**

Logical operators are used to combine two or more conditions or to complement the evaluation of the original condition.

Operator | Description | Syntax |
---|---|---|

&& | Logical AND: true if both operands are true | x && y |

|| | Logical OR: true if one of operands is true | x || y |

! | Logical NOT: true if operand is false | !x |

**Assignment Operators**

Assignment operators are used to assign values from right side operands to left side operands.

Operator | Description | Syntax |
---|---|---|

= | Assign value from r.h.s to l.h.s | x = y + z |

+= | a = a + b | a += b |

-= | a = a – b | a -= b |

*= | a = a * b | a *= b |

/= | a = a / b | a /= b |

\= | a = a \ b | a \= b |

%= | a = a % b | a %= b |

^= | a = a ^ b | a ^= b |

&= | a = a & b | a &= b |

|= | a = a | b | a |= b |

>>>= | a = a >>> b | a >>>= b |

>>= | a = a >> b | a >>= b |

<<= | a = a << b | a <<= b |

**Vectorized dot(.) Operator**

The “dot” operator is used to perform element wise binary operations on a given array.

Syntax: Prepend dot operator to the desired binary operation.

x = x .^ 2

As you can see from this example, doing A = A ^ 2 will result in an error since it is not possible to perform square of an array, on the other hand if the dot operator is used, the squaring will be done element wise.

**Relational Operators**

Relational operators are used to check the relation between 2 operands.

Operator | Description | Syntax |
---|---|---|

> | Greater than | x > y |

< | Less than | x < y |

!ERROR! unexpected operator '=' | Equal to | x == y |

!=, ≠ | Not equal to | x != y or x ≠ y |

>=, ≥ | Greater than or equal to | x >= y or x ≥ y |

<=, ≤ | Less than or equal to | x <= y or x ≤ y |