Julia is a powerful/efficient/high-level computer programming language. You can get into interacting mode right-away with:
julia
Exit with exit(). One may also also use Wolfram's notebook concept:
jupyter-notebook
We will often need to install packages, which, back to julia, is done as follows:
using Pkg Pkg.add("IJulia")
Then, from a terminal, jupyter-notebook opens a session in a browser, in which one can start a Julia session with a New invocation (and choosing julia there).
There are some conventions in computer programming which become natural as you get used to them. For instance, $x=3$ takes a different meaning in most languages than in Mathematics. In the latter case, it means that the variable $x$ has the same value as the number 3. For a computer x=3 assigns the value 3 to the variable x. In Julia that becomes:
julia> x=3 3
The output 3 is the result of our line of code, which reads: assigns the value 3 to x. The result of this is 3. In maths, if $x=3$, then $x\neq 4$, while in computer code, following x=3, we can have x=4 meaning we now assign the value 4 to x. The computer code equivalent of the mathematical $=$ is actually ==. Indeed:
julia> x=4 4 julia> x==3 false
A typical line of code is to increment the value of a variable, which in many cases we would refer to as a counter:
x=x+1
Note that in Maths, this equality is trivially wrong. In computer code, on the other hand, it is so useful that we even have a special notation for it:
x+=1
Incrementing the value of x and storing the result:
julia> x=4 4 julia> x+=1 5
A very early computer language which defined much of the conventions, notations and overall syntax of computer programming is C. An improved (and modernized) version implementing object-programming is known as C++, implying the joke it's an added version of C.
Most conventions are natural or familiar already
julia> 3>2 true julia> 17<=5 false julia> 1+5!=2+3 true
but some others, we're not even sure we really want them:
julia> 7/2==2\7 true
(this is called inverse division). More useful is the remainder $r$ from Euclidean division $a=bq+r$ which is obtained as a%b, for instance, $17=3\times 5+2$ so
julia> 17%5 2 julia> 17%3 2
so for instance, when we found that it was taking 205s for the computer of a dumb programmer to compute a Fibonacci number, we could give a better idea of the poor performance by giving the time in minutes:
julia> floor(204/60) 3.0 julia> 204%60 25
where we used floor to extract the integer part (to lowest value; we'd use ceil for the highest value and round for the closest value).
Julia also has basic symbolic abilities, beyond numerical ones:
julia> 24/9 2.6666666666666665 julia> 24//9 8//3 julia> numerator(1389//234) 463
Julia knows about important constants:
julia> pi π = 3.1415926535897...
It even supports unicode. We could use such characters using LaTeX encoding and tab:
\alpha+[tab]→α
that we can use as a variable. In some cases it could be useful, compare for instance:
julia> 5≥2 true julia> 5>=2 true julia> 5=>2 5 => 2
where the top version was input as \ge+[tab]. If you know the unicode code, you can enter it as "\uXXXX". For instance:
julia> c="\u2020" "†"
By the way, we have just introduced a new type of "variable", that we don't find in maths. So-called strings:
julia> hello="Hi there!" "Hi there!" julia> hello "Hi there!"
You can somehow "operate" on such things as well. Here's concatenation, or joining strings:
julia> hello*" Hey, you!" "Hi there! Hey, you!"
Strings are clearly important in computer programming, as we deal a lot with texts. We shall see concepts such as regular expressions that allow powerful text processing, e.g.,
julia> replace("Julia", "a" => "us") "Julius"
But for now, we'll be more concerned on the numerical aspect. In this context, another type of variable that is very useful is the concept of arrays, which is a list or vector. Here's an array of 10 consecutive integers:
julia> a = [1:10;] 10-element Array{Int64,1}: 1 2 3 4 5 6 7 8 9 10
Things can quickly go from completely obvious to quite tricky. Consider the following:
julia> b=a 10-element Array{Int64,1}: 1 2 3 4 5 6 7 8 9 10 julia> b[5]+=1 6
We have incremented the 5th element of b by one, so that:
julia> b 10-element Array{Int64,1}: 1 2 3 4 6 6 7 8 9 10
Now for the tricky part. what do you think happens with:
a==b
The answer is true. This is counterintuitive because with "variables" rather than arrays, we get a different results:
julia> α=5 5 julia> β=α 5 julia> β+=1 6 julia> α==β false
This is because the command b=a does not copy the array a into b (it does for the variables), but it copied the "address" of the array in memory. If we want to duplicate an independent array, we must do:
ulia> b=copy(a) 10-element Array{Int64,1}: 1 2 3 4 7 6 7 8 9 10
Now changing b[5] does not change a[5]. Be careful of these kinds of subtle things, they are the source of many mistakes (or "bugs", as we call them).
Incrementing a counter is a good way to keep track of what is going, along with control flow. The most famous are:
Let us now play with things computers are good at, to start with, plotting: