2  First Contact

This chapter helps you get started. It omits many details, and the code examples are often not optimal.

2.1 Julia as a Calculator

Compute the following: \(\qquad 12^{1/3} + \frac{3\sqrt{2}}{\sin(0.5)-\cos(\frac{\pi}{4})\log(3)}+ e^5\)

12^(1/3) + 3sqrt(2) / (sin(.5) - cos(pi/4)*log(3)) + exp(5)
136.43732662344087

Note that:

  • Powers are written as a^b.
  • The constant π is predefined.
  • log() is the natural logarithm.
  • The multiplication operator * can be omitted after a number when followed by a variable, function, or opening parenthesis.

2.2 The most important keys: Tab and ?

When programming, press the Tab key as soon as you’ve typed 2–3 letters of a word. Potential completions are then displayed or completed if the completion is unique. This saves time and you learn a lot about Julia.

lo  Tab
log
lock
log2
log1p
log10
local
logrange
lowercase
load_path
lowercasefirst
locate_package
pri  Tab
print
println
printstyled
primitive type

Julia’s built-in help system ?name provides comprehensive documentation for all functions and constructs. Here is a relatively brief example:

?for
search: for nor xor foldr floor Core sort
for

for loops repeatedly evaluate a block of statements while iterating over a sequence of values.

The iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer to reuse an existing local variable for iteration.

Examples

julia> for i in [1, 4, 0]
           println(i)
       end
1
4
0

2.3 Variables and Assignments

Variables are created through assignment with the assignment operator =.

x = 1 + sqrt(5) 
y = x / 2
1.618033988749895

In interactive mode, Julia displays the result of the last statement.

Note

Assignments are not mathematical equations. The semantics of the assignment operator (the equals sign) is:

  • Compute the right side and
  • Assign the result to the left side.

Expressions like x + y = sin(2) are therefore invalid. Only a variable name may appear on the left side.

2.4 Data types

Julia is a strongly typed language where every object has a type. Among the fundamental types are:

  • Integers
  • Floating-point numbers
  • Strings
  • Booleans.

The type of a variable can be determined using the typeof() function.

for x  (42, 12.0, 3.3e4, "Hello!", true)
    println("x = ", x, " ... Type: ", typeof(x))
end
x = 42 ... Type: Int64
x = 12.0 ... Type: Float64
x = 33000.0 ... Type: Float64
x = Hello! ... Type: String
x = true ... Type: Bool

The standard floating-point number has a size of 64 bits, which corresponds to a double in C/C++/Java.

Julia is a dynamically typed language. Variables have no type; they are typeless references (pointers) to typed objects. When people speak of the “type of a variable”, they mean the type of the object currently assigned to the variable.

x = sqrt(2)

println( typeof(x), " - Value of x = $x" )

x = "Now I'm no longer a floating-point number!"

println( typeof(x), "  - Value of x = $x" )
Float64 - Value of x = 1.4142135623730951
String  - Value of x = Now I'm no longer a floating-point number!

2.6 Functions

Function definitions begin with the keyword function and end with the keyword end. Typically, they have one or more arguments and return a computed result via a return statement.

function hypotenuse(a, b)    # a bit cumbersome
    c2 = a^2 + b^2
    c  = sqrt(c2)
    return c 
end
hypotenuse (generic function with 1 method)

After definition, the function can be used (called). The variables a,b,c,c2 used in the definition are local and not available outside the function definition.

x = 3
z = hypotenuse(x, 4)
println("z = $z")
println("c = $c")
z = 5.0
UndefVarError: `c` not defined in `Main.Notebook`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
 [1] top-level scope
   @ ~/Julia/Book26/JuliaBook/chapters/first_contact.qmd:219

Very simple functions can also be defined as one-liners:

hypotenuse(a, b) = sqrt(a^2+b^2)
hypotenuse (generic function with 1 method)

2.7 Tests

Tests return a Boolean value (true or false).

x = 3^2
x < 2^3
false

In addition to the usual arithmetic comparisons ==, !=, <, <=, >, >= there are many other tests. The result of a test can also be assigned to a variable, which is then of type Bool. The logical operators &&, || and negation ! can be used in tests.

test1 = "Car" in ["Bicycle", "Car", "Train"]
test2 = x == 100 ||  !(x <= 30 && x > 8)
test3 = startswith("lampshade", "Lamp") 
println("$test1 $test2 $test3")
true false false

2.8 Conditional Statements

A simple if statement has the form

if <test> 
    <statement1> 
    <statement2>
    ...
end

There can be one or more elseif blocks and an optional final else block.

x = sqrt(100)

if x > 20
    println("Strange!")
else
    println("OK")
    y = x + 3
end
OK
13.0

Indentation enhances readability but is optional. Line breaks separate statements, as do semicolons. The code above is equivalent to the following single line in Julia:

# Please don't program like this! You will regret it!
x=sqrt(100); if x > 20 println("Strange!") else println("OK"); y = x + 3 end
OK
13.0

2.9 Simple for loops

for loops for repeating the execution of statements have the form

for  <counter> = start:end
    <statement1> 
    <statement2>
    ...
end

Example:

sum = 0
for i = 1:100
    sum = sum + i
end 
sum
5050

2.10 Arrays

One-dimensional arrays (vectors) are a simple container type. They can be created with square brackets and accessed by index, with indexing starting at 1.

v = [12, 33.2,  17, 19, 22]
5-element Vector{Float64}:
 12.0
 33.2
 17.0
 19.0
 22.0
typeof(v)
Vector{Float64} (alias for Array{Float64, 1})
v[1] = v[4] + 10
v
5-element Vector{Float64}:
 29.0
 33.2
 17.0
 19.0
 22.0

Empty vectors can be created and extended with push!().

v = []     # empty vector
push!(v, 42)
push!(v, 13)
v
2-element Vector{Any}:
 42
 13
using REPL
function Tab(s)
    dc = map(x->x.name, REPL.doc_completions(s))
    l = filter(x->startswith(x,s), dc)
    println.(l)
    return   # return nothing, since broadcast println produces empty vector
end

 = |>     # https://docs.julialang.org/en/v1/manual/functions/#Function-composition-and-piping

pri = "pri";
pri  Tab
print
println
printstyled
primitive type