# COSC441 Assignment 3, 2017

The purpose of this assignment is to get you to create a very simple threaded program in Erlang.

You are to write a module in Erlang, called a3.erl. It will export a function of two arguments, also called a3. a3(N, T) will compute the square root of the sum of the numbers from 1 to N using T threads. You can call it like this:

```% erl
1> c(a3).
2> a3:a3(1000000, 10).
```

where the first line starts the Erlang shell, the second line compiles and loads the module, and the third line calls the function.

The a3/2 function is to create T threads, each knowing the range of numbers it is to work on. When each thread has finished, it is to send its result back to the original thread. The original thread will receive these rules, add them, and return the square root of the sum.

Submit your assignment within one week by sending an e-mail message to `ok@cs.otago.ac.nz` with the subject "COSC441 Assignment 3" and just the a3.erl file. Any comments you wish to make should be comments inside that file. Erlang comments begin with "%" and extend to the end of the line.

The purpose of this assignment is to get you writing a little Erlang program. It's not supposed to be a puzzle. So here is a quick reference to some of the things you will need, which is why you should only need one week. Get onto it quickly!

• Erlang numbers can be integers or (64-bit IEEE) floats. There is no fixed bound on the size of an integer. Given the definition
```factorial(N)
when is_integer(N), N >= 0 ->
factorial_loop(N, 1).

factorial_loop(0, F) ->
F;
factorial_loop(N, F) ->
factorial_loop(N-1, N*F).
```

a call to factorial(40) will give the answer 815915283247897734345611269596115894272000000000 exactly.

• The arithmetic operations + - * do the usual things. Integer division and remainder are done with the operators div and rem (not mod); the / operator always gives a floating-point answer. Numbers may be compared using < =< > >= == and =/=. Note that “less than or equal to” is written with the equal sign first; <= is not legal in Erlang. (This goes back to Prolog programs using => and <= for arrows.)
• Looping is done in one of three ways.
• As in the factorial example above, you may do it “by hand” using recursion.
• You may use higher-order functions. These take one or more functions as parameters. Inside they work by recursion, but that's not visible in your code.
• If you want to iterate over a list, you may use a “list comprehension” [expr || pattern <- list, condition] which selects elements of (the value of) list that match pattern and satisfy the condition, for each of them computes the corresponding value of expr, and collects those values in a list.

For example, we can define

```product(Numbers) ->
product(Numbers, 1).

product([], Accumulator) ->
Accumulator;
product([Number | Numbers], Accumulator) ->
product(Numbers, Accumulator * Number).
```

Then we can use the library function lists:seq(From, To) and write

```factorial(N) ->
product(lists:seq(1, N)).
```
• Ordinary functions have a name (which is an identifier) and an arity (which is a non-negative integer saying how many arguments the function has). Two functions with the same name but different arities are different functions. (For example, product/1 and product/2 above.)
• Functions may have many clauses separated by semicolons and end with a full stop. The last clause must have a full stop, not a semicolon. Two clauses for the same function must be separated by a semicolon, not a full stop. There's no deep reason for this. A clause has a head and a body separated by an arrow ->. A clause may also have a guard between the head and the arrow. Guards use similar syntax to expressions but are not expression. (Again, this goes back to concurrent logic programming languages like Logix, Parlog, and Guarded Horn Clauses.) A clause is selected when its head matches the arguments and its guard (if any) is true.
• Anonymous functions are written
```fun (...) [when ...] -> ...
; (...) [when ...] -> ...
; (...) [when ...] -> ...
end
```

They may have multiple clauses. For example, you could write an anonymous "maximum" function as

```fun (X, Y) when X >= Y -> X
; (X, Y) when X =< Y -> Y
end
```

No function has to have more than one clause if you don't want it to.

• The simplest way to create a thread is to use the built-in spawn/1 function, passing it an anonymous function of no arguments, e.g.,
```    spawn(fun () -> handler(Lower_Bound, Upper_Bound) end)
```
• If you want the new thread to be able to send results back to the parent thread, you have to tell it the parent thread's identity. You get that from self/0, but you must call that in the parent thread, not the child thread. So
```    Parent = self(),
spawn(fun () ->
handler(Self, Lower_Bound, Upper_Bound) end)
```
```receive
pattern [when guard] -> body
; pattern [when guard] -> body
...
[  after timeout -> body
end
```

A clause of a receive expression is selected when there is a message in the caller's mailbox that matches the pattern and makes the guard true. When that happens the message is removed from the mailbox.

• Erlang has no assignment statements. Variables are written beginning with a capital letter. Variables are bound to values once and only once. It's what we call a Single Assignment language. There are no mutable variables as such.
• Finally, a module is written
```-module(name).
-export([f1/n1, ..., fk/nk].
function declaration.
...
```

where -export may be repeated. A function defined inside a module is callable from outside if and only if its name/arity pair is listed in an -export declaration.