```
In [1]:
```x=1+2im

```
Out[1]:
```

```
In [2]:
```typeof(x)

```
Out[2]:
```

`re`

) and an imaginary part (denoted `im`

). Fields of a type can be accessed using the `.`

notation:

```
In [3]:
```x.re

```
Out[3]:
```

```
In [4]:
```x.im

```
Out[4]:
```

`r`

and `θ`

. This is done using the `type`

syntax, followed by a list of names for the fields, and finally the keyword `end`

```
In [5]:
```type MyComplex
r
θ
end

```
In [6]:
```z=MyComplex(1,0.1)

```
Out[6]:
```

We can access fields for our new type using `.r`

and `.θ`

:

```
In [7]:
```z.θ

```
Out[7]:
```

```
In [8]:
```z.r, z.θ

```
Out[8]:
```

```
In [9]:
```typeof(ans)

```
Out[9]:
```

```
In [10]:
```function sq(x)
x^2
end

```
Out[10]:
```

```
In [11]:
```sq(2),sq(3)

```
Out[11]:
```

`,`

. Here's a function that takes in 3 arguments and returns the average. (We write it on 3 lines only to show that functions can take multiple lines.)

```
In [12]:
```function av(x,y,z)
ret=x+y
ret=ret+z
ret/3
end

```
Out[12]:
```

```
In [13]:
```av(1,2,3)

```
Out[13]:
```

Variables live in different scopes. In the previous example, `x`

, `y`

, `z`

and `ret`

are *local variables*: they only exist inside of `av`

. So this means `x`

and `z`

are *not* the same as our complex number `x`

and `z`

defined above.

Note: This is only true for x, y and z because they are bit types. If they are arrays, a function will change 'surrounding' x, y and z values.

Warning: if you reference variables not defined inside the function, they will use the outer scope definition. The following example shows that if we mistype the first argument as `xx`

, then it takes on the outer scope definition `x`

, which is a complex number

```
In [14]:
```function av2(xx,y,z)
(x+y+z)/3
end

```
Out[14]:
```

```
In [15]:
```av2(5,6,7)

```
Out[15]:
```

```
In [16]:
```v=[1; 2; 3; 4; 5] # Note the use of ';' to create a vector
function suminlastentry(v::Vector{Int64})
v[end]=sum(v)
end
suminlastentry(v)
v

```
Out[16]:
```

```
In [17]:
```v=[1 2 3 4 5]

```
Out[17]:
```

```
In [18]:
```v=[1, 2, 3, 4, 5]

```
Out[18]:
```

In Julia 0.5 this also works, but:

```
In [21]:
```m=[1 2 3 4 5;]

```
Out[21]:
```

```
In [22]:
```m=[1 2 3;4 5 6] # Replacing the ';' by a ',' will give an error

```
Out[22]:
```

```
In [116]:
```v=rand(Int,5)
w=rand(Int,10)
length(v),length(w)

```
Out[116]:
```

`for`

keyword. The following syntax evaluates the body of the for loop (between the lines after the `for`

and before the `end`

) one by one for `k`

equal to every number in the range `1:10`

.

```
In [118]:
```for k=1:5
k2=k^2
println(k2)
end

```
```

```
In [119]:
```k=1
k2=k^2
println(k2)
k=2
k2=k^2
println(k2)
k=3
k2=k^2
println(k2)
k=4
k2=k^2
println(k2)
k=5
k2=k^2
println(k2)

```
```

`k`

through every index of a vector. The following calculates the sum of the entries of the vector, printing out the current value for each value of k

```
In [120]:
```v=[1,5,6,3]
ret=0
for k=1:length(v)
ret=ret+v[k]
println("At step $k, the current sum is $ret")
end
ret

```
Out[120]:
```

We are now ready to write a function that calculates the average of the entries of a vector:

```
In [39]:
```function vecav(v)
ret=0
for k=1:length(v)
ret=ret+v[k]
end
ret/length(v)
end

```
Out[39]:
```

```
In [122]:
```vecav([1,5,2,3,8,2])

```
Out[122]:
```

julia has an inbuilt `sum`

command that we can use to check our code:

```
In [123]:
```sum([1,5,2,3,8,2])/6

```
Out[123]:
```

functions can be defined only for specific types using `::`

after the variable name. The same function name can be used with different type signatures.

The following defines a function `mydot`

that calculates the dot product, with a definition changing depending on whether it is an `Integer`

or a `Vector`

. Note that `Integer`

means any kind of integer: `mydot`

is defined for pairs of Int64's, Int32's, etc.

```
In [124]:
```function mydot(a::Integer,b::Integer)
a*b
end
function mydot(a::Vector,b::Vector)
# we assume length(a) == length(b)
ret=0
for k=1:length(a)
ret=ret+a[k]*b[k]
end
ret
end

```
Out[124]:
```

```
In [125]:
```mydot(5,6) # calls the first definition

```
Out[125]:
```

```
In [126]:
```mydot(Int8(5),Int8(6)) # also calls the first definition

```
Out[126]:
```

```
In [127]:
```mydot([1,2,3],[4,5,6]) # calls the second definition

```
Out[127]:
```

```
In [128]:
```mydot([1,2,3,4],[4,5,6]) # an error is thrown because length(a) > length(b)

```
```

We should actually check that the lengths of `a`

and `b`

match. Let's rewrite `mydot`

using an `if`

, `else`

statement. The following code only does the for loop if the length of a is equal to the length of b, otherwise, it throws an error.

Note that `==`

checks if two quantities are equal. This is *not the same* as `=`

, which assigns the value of one quantity to the other

If we name something with the exact same signature (name, and argument types), previous definitions get overriden.

```
In [129]:
```function mydot(a::Vector,b::Vector)
ret=0
if length(a) == length(b)
for k=1:length(a)
ret=ret+a[k]*b[k]
end
else
error("arguments have different lengths")
end
ret
end

```
Out[129]:
```

```
In [130]:
```mydot([1,2,3,4],[5,6,7,8])

```
Out[130]:
```

```
In [131]:
```mydot([1,2,3,4],[5,6,7])

```
```

```
In [57]:
```r=Ref(1)
r.x

```
Out[57]:
```

`Ref`

is just a composite type with a single field called `x`

. We can make our own version of `Ref`

called `MyRef`

:

```
In [132]:
```type MyRef
x
end

The function call `MyRef(52)`

creates a new `MyRef`

, with `x`

initialized as 52:

```
In [133]:
```myref=MyRef(52)

```
Out[133]:
```

```
In [134]:
```myref.x

```
Out[134]:
```

we can create another variable `n`

that is equal to `myref`

.

```
In [135]:
```n=myref

```
Out[135]:
```

Unlike bittypes, the fields of composite types point to locations in memory that store the values. In this example, `myref.x`

lives somewhere in memory, let's say at address 1543. But setting `n=myref`

has the property that all the fields of `n`

also point to the same location in memory. This means `n.x`

also points to address 1543.

So if we change the value of `myref.x`

to 6, this changes the value living in address 1543 to 6, and so `n.x`

is also automatically 6:

```
In [136]:
```myref.x=6

```
Out[136]:
```

```
In [137]:
```n.x

```
Out[137]:
```

`myrefx`

and `nx`

are in two different locations in memory, let's say 1765 and 1987, and the `=`

copies the value 52 from `myrefx`

's address 1765 to `nx`

's address 1987. Then calling `myrefx=6`

actually creates a new address in memory, let's say 2076, with the value of 6. But `nx`

still corresponds to 1987, and is still 52.

```
In [138]:
```myrefx=52
nx=myrefx
myrefx=6
nx

```
Out[138]:
```

Here is another example. Let's return to the composite type set-up:

```
In [139]:
```myref=MyRef(52)
myref.x
n=myref

```
Out[139]:
```

`myref.x=6`

we call `myref=MyRef(6)`

, this creates a brand new `MyRef`

,
with the new `myref.x`

pointing to a new address in memory (let's say 6543) initialized with
the value 6. Whereas `n.x`

still points to the same address in memory as the old `myref.x`

,
so is still 52:

```
In [67]:
```myref=MyRef(6)

```
Out[67]:
```

```
In [68]:
```n.x

```
Out[68]:
```

```
In [141]:
```v=[1,2,3,4]
w=v

```
Out[141]:
```

You can change values of a vector using brackets and =:

```
In [142]:
```v[2]=52

```
Out[142]:
```

This has changed v:

```
In [72]:
``````
v
```

```
Out[72]:
```

But it's also changed w, since w points to the same location in memory as v:

```
In [143]:
``````
w
```

```
Out[143]:
```

If we assign v to a new vector, w still points to the old location in memory, so is unchanged.

Makes sure it is clear the difference between `v=`

, which reassigns the variable v to a new value, and `v[1]=`

, which leaves v the same, but modifies a value in memory.

```
In [74]:
```v=[6,75]

```
Out[74]:
```

```
In [75]:
``````
w
```

```
Out[75]:
```

If you actually want to copy the entries of a vector, without pointing to a new vector, use `copy`

:

```
In [147]:
```v=[6,75]
w=v
w2=copy(v)

```
Out[147]:
```

```
In [148]:
```v[1]=2

```
Out[148]:
```

```
In [150]:
``````
w
```

```
Out[150]:
```

```
In [149]:
``````
w2
```

```
Out[149]:
```

```
In [153]:
```x=1/2
typeof(x)

```
Out[153]:
```

```
In [154]:
```y=1/3
typeof(y)
bits(y)

```
Out[154]:
```

```
In [155]:
```x=1.0
bits(x)

```
Out[155]:
```