Videos related to this segment (click the title to watch)
01 JULIA1 - 1A: Introduction and setup of the environment (8:37)
01 JULIA1 - 1B: Comments, code organisation, Unicode support, broadcasting (12:4)
01 JULIA1 - 1C: Math operators, quotation marks (6:49)
01 JULIA1 - 1D: Missing values (10:4)
01 JULIA1 - 1E: Stochasticity in programming (9:14)

0101 - Basic Syntax Elements

Some stuff to set-up the environment..

julia> cd(@__DIR__)
julia> using Pkg
julia> Pkg.activate(".") Activating project at `~/work/SPMLJ/SPMLJ/buildedDoc/01_-_JULIA1_-_Basic_Julia_programming`
julia> ENV["PYTHON"] = "" # This will be needed in a further segment""
julia> ENV["R_HOME"] = "*" # This will be needed in a further segment # If using a Julia version different than 1.10 please uncomment and run the following line (reproducibility guarantee will however be lost) # Pkg.resolve()"*"
julia> Pkg.instantiate()
julia> using Random
julia> Random.seed!(123)Random.TaskLocalRNG()

Comments

Similar to many other languages, everything that folows a hash symbol (#), up to the end of the line, is considered by Julia as a comment. Julia supports also multi-line, middle-of-the-line and nested comments using the #= ...comment... =# syntax:

julia> # This is a comment
       a = 1 # also this one1
julia> a = #= also this one =# 1 #= also #= this =# one =#1

Code organisation

Delimiting the end of a programming statement with a semi-colon, is optional, and has the effect to block the normal display on the terminal of the output of that statement.

julia> # Semicolon:
       a = 11
julia> a = 1;

All code blocks (like the foor loop that we'll study in detail in the Control flow and functions segment) ends with the end keyword, like in the example below:

julia> for i in 1:3
          println("i is $i")
       end # Keyword `end` to finish a blocki is 1
i is 2
i is 3

Function calls require to specify the name of the function to call followed straight away (without spaces) with the function arguments inside round brackets:

julia> println("Hello world!")
       ##println ("This would error!")Hello world!

Unicode support

We can can use any fancy Unicode symbol, including modifiers, in the names of variables, types, functions..

julia> using Statistics # for the `mean` function, in the Standard Library
julia> σ²(x) = sum( (x .- mean(x)).^2 )/length(x) # The superscript `²` is just another character, it has no syntactic value.σ² (generic function with 1 method)
julia> σ²([1,2,3])0.6666666666666666
julia> x̄ₙ = 1010
julia> vàlidVarNαme! = 22
julia> 🥞 = 88
julia> 🍴(🥫,parts=4) = 🥫/parts🍴 (generic function with 2 methods)
julia> 🍰 = 🍴(🥞)2.0

Broadcasting

Broadcasting refers to the capacity to dispatch a function that accepts a scalar argument to a whole collection. Broadcasting will then call the function with each individual element of the collection. It is implemented by postfixing a function name (or prefixing an operator) with a single dot at call time:

julia> 10 .+ [1,2,3]3-element Vector{Int64}:
 11
 12
 13
julia> add2(x) = x + 2add2 (generic function with 1 method)
julia> add2(10) # add2([1,2,3]) # would return an error12
julia> add2.([1,2,3]) # any, including user defined functions, can be broadcasted. No need for map, for loops, etc..3-element Vector{Int64}: 3 4 5
julia> add2.((1,2,3)) # not only for arrays, here is a Tuple(3, 4, 5)
julia> add2.(Set([1,2,3,2])) # and here a Set3-element Vector{Int64}: 4 5 3
julia> .+([1,2,3],[10,20,30]) # fine here # .+([1,2,3],[10,20]) # DimensionMismatch error: the input of the the broadcasted arguments must have the same size or be a scalar3-element Vector{Int64}: 11 22 33

To "protect" one specific argument to be broadcasted, use Ref(arg):

julia> foo(x,y::AbstractArray) = [yi+x for yi in y] # a function that wants the first argument as scalar and the second as vectorfoo (generic function with 1 method)
julia> foo(1,[10,20]) # foo.([1,2],[10,20]) # error, as we try to broadcast also the seond element, but we can't call `foo` with two integers2-element Vector{Int64}: 11 21
julia> foo.([1,2],Ref([10,20])) # now it is fine, we broadcast only the first argument2-element Vector{Vector{Int64}}: [11, 21] [12, 22]

1 based arrays

Arrays start indexing at 1 (like R, Fortran, Matlab,...) instead of 0 (like in C, Python, Java...)

julia> a = [1,2,3]3-element Vector{Int64}:
 1
 2
 3
julia> a[1]1
julia> collect(1:3) # in ranges, both extremes are included3-element Vector{Int64}: 1 2 3
0 or 1 ?

Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration. –Stan Kelly-Bootle

Basic Mathematic operations

All standard mathematical arithmetic operators (+,-,*,/) are supported in the obvious way:

julia> a = 2^4         # rise to power16
julia> b = ℯ^2; #= or =# b = exp(2) # Exponential with base ℯ7.38905609893065
julia> d = log(7.3890) # base ℯ1.9999924078065106
julia> e = log(10,100) # custom base2.0
julia> f = 5 ÷ 2 # integer division2
julia> e = 5 % 2 # reminder (modulo operator)1
julia> a = 2//3 + 1//3 # rational numbers1//1
julia> typeof(a)Rational{Int64}
julia> π == pi # some irrational constantstrue
julia> typeof(ℯ)Irrational{:ℯ}
julia> convert(Float64,a)1.0

Quotation

julia> a = 'k'              # single quotation mark: a single Char'k': ASCII/Unicode U+006B (category Ll: Letter, lowercase)
julia> b = "k" # double quotation mark: a (Unicode) String #c = 'hello' # error !"k"
julia> c = "hello""hello"
julia> d = `echo hello` # backtick: define a command to (later) run (e.g. on the OS)`echo hello`
julia> e = """a multiline string""""a\nmultiline\nstring"
julia> println(c)hello
julia> println(e)a multiline string
julia> using Markdown
julia> f = md"""a **markdown** _string_""" a markdown string

Missingness implementations

Attention to these three different implementations (of 3 different concepts) of "missingness":

julia> a = nothing # C-style, "software engineer's null → run-time error
julia> b = missing # Data scientist's null → silent propagationmissing
julia> c = NaN # Not a number → silent propagationNaN
julia> typeof(a)Nothing
julia> typeof(b)Missing
julia> typeof(c)Float64
julia> d = 0/0 # a2 = mean([1,a,3]) # would errorNaN
julia> b2 = mean([1,b,3])missing
julia> c2 = mean([1,c,3])NaN
julia> b3 = mean(skipmissing([1,b,3]))2.0
julia> b == missing # propagatemissing
julia> ismissing(b)true
julia> isequal(b,2) # exception to the propagation rule, it allows a comparison when one of the item may be missingfalse
julia> isequal(b,missing)true
julia> b4 = [1,missing,3]3-element Vector{Union{Missing, Int64}}: 1 missing 3
julia> typeof(b4)Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})
julia> eltype(b4)Union{Missing, Int64}
julia> nonmissingtype(eltype(b4))Int64

Random values

julia> rand()       # [0,1] continuous0.521213795535383
julia> rand(30:40) # [30,40] integer36
julia> rand(30:0.01:40) # [30,40] with precision to the second digit38.91
julia> using Distributions
julia> rand(Exponential(10)) # We'll see Distributions more in detail in the Scientific Programming lesson3.5106443155652722
julia> rand(30:40,3) # A vector of 3 random numbers.3-element Vector{Int64}: 35 34 30
julia> rand(Exponential(10),3,4) # Same syntax for sampling from any distribution !3×4 Matrix{Float64}: 5.99452 9.34169 15.9134 1.18909 14.3277 9.82636 4.77897 5.75527 7.6609 0.507418 1.99239 5.45417
julia> using Random
julia> myRNG = MersenneTwister(123) # use StableRNG for a RNG guaranteed to remain stable between Julia-versionsRandom.MersenneTwister(123)
julia> a1 = rand(myRNG,10:1000,5)5-element Vector{Int64}: 959 364 276 490 635
julia> a2 = rand(myRNG,10:1000,5)5-element Vector{Int64}: 511 431 906 288 550
julia> a1 == a2false
julia> myRNG = MersenneTwister(123)Random.MersenneTwister(123)
julia> b1 = rand(myRNG,10:1000,5)5-element Vector{Int64}: 959 364 276 490 635
julia> b2 = rand(myRNG,10:1000,5)5-element Vector{Int64}: 511 431 906 288 550
julia> b1 == b2false
julia> a1 == b1true
julia> a2 == b2true
julia> a = rand(myRNG,Exponential(10),5)5-element Vector{Float64}: 0.08730194128784134 34.98193102162552 2.8516248856399145 12.990776241562488 7.330776791908584

View this file on Github.


This page was generated using Literate.jl.