Answers for exam 101215. Please note that this file was written for my
personal use and may be incomplete.

Sven-Olof Nyström


* 1.  

The problem was not very well stated. Responses should be tagged, but
I did not ask for that. In fact, the question might be understood as
if I did *not* want that.

In future questions of this type, I'll try to be more careful in
stating the expected interface.

For code, see the answer to next question.


* 2. 

-module(cell).

-compile(export_all).

make_cell(Key, Value) ->
    spawn(cell, loop, [Key,Value, []]).

loop(Key, Value, Children) ->
    receive 
        {add_child, C} ->
            loop(Key, Value, [C|Children]);
        {try_key, K, P} when K == Key ->
            P ! {value, Value, self()},
            loop(Key, Value, Children);
        {try_key, K, P} when K /= Key ->
            spawn(cell, ask_all_children, [K, Children, P, self(), 0]),
            loop(Key, Value, Children)
    end.

ask_all_children(_K, [], P, S, Acc) ->
    P ! {value, Acc, S};
ask_all_children(K, [C|Cs], P, S, Acc) ->
    C ! {try_key, K, self()},
    receive 
        {value, Value, C} ->
            ask_all_children(K, Cs, P, S,  Acc+Value)
    end.
        

Note: This one is pretty hard. Be generous to anyone who understood
that you need to create a process to handle the replies from the
children.

 + collect results





* 3.  For in CL



(defmacro for (var start end &rest body)
  (let ((index (gensym "INDEX"))
        (start-name (gensym "START")))
    `(let ((,start-name ,start))
       (dotimes (,index (- ,end ,start-name))
         (let ((,var (+ ,index ,start-name)))
           ,@body)))))  

(defun test () 
  (for i 0 10
       (print i)))

(defun test2 () 
  (for i 0 4
     (for j 0 i
        (print (list i j)))))

* 4. Infinite product

merge [] ys = ys
merge (x:xs) ys = x : (merge ys xs)

makepairs [] _ = []
makepairs (x:xs) ys = 
    merge [(x,y)| y <- ys] (makepairs xs ys)

Haha. This one gets into trouble for the following input:

makepairs [1..][]

Guess this means that I am not infallible. Oh well.

(the problem can easily be solved by adding a clause makepairs _ [] = [])


* 5. Type classes. Overloading.

Simple stuff like the weight example.

 - like interfaces in Java

 - example Eq

 - use Eq in specification of member






* 6. Continuation.


-module(subseq).

-compile(export_all).

subseq(N, [], C) when N == 0 ->
    C([]);
subseq(N, [], C) when N =/= 0 ->
    true;
subseq(N, [X|L], C) ->
    subseq(N-X, L, fun (R) ->
                           C([X|R])
                   end),
    subseq(N, L, C).

Of course, a simpler strategy may be to build a list of all
subsequences and then filter out the correct results. That was not
what I wanted.


* 7.

Here I want to hear something sensible about environments and closures.