﻿ %Class 10 : Multi-Tasking Map
% David Evans
% 2013-09-26

<!--
Title: Class 10: 
Date: 2013-09-26
Category: Classes
Tags: map, MapReduce, Rust, smart pointers, multi-threading, processes, threads, tasks
Author: David Evans
-->

<!-- <center>
<iframe src="http://www.slideshare.net/slideshow/embed_code/26363780" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

</center>
-->

## Action Items

<div class="startaction"></div>

**<a href="http://www.cs.virginia.edu/evans/cs4414-fall2013/pages/ps2.html">PS2
is due Monday, September 30</a>.**  The submission form for PS2 will be
posted soon.  As part of submitting PS2, you will schedule a short (10
minute) demo/review with one of the course staff.  All team members are
expected to participate in the demo, except in exceptional
circumstances.  At the demo, you should be prepared to show off your
shell and will be asked to try some specific things in your shell and
explain things about what happens, as well as answering questions about
your design and implementation.

<div class="endaction"></div>

# Sequential Map

````rust
struct Node {
    head : int,
    tail : Option<~Node>
}

type List = Option<~Node> ;

trait Map {
    fn mapr(&self, &fn(int) -> int) -> List;
}

impl Map for List {
    fn mapr(&self, f: &fn(int) -> int) -> List {
         match(*self) {
            None => None,
            Some(ref node) => { Some(~Node{ head: f(node.head), tail: node.tail.mapr(f) }) },
        } 
	} 
}
````

You should understand everything in this code.  If you don't feel
comfortable with functions that take other functions as inputs or return
new functions as results and recursive data structions and procedures on
them, you should read John McCarthy's [_Recursive Functions of Symbolic
Expressions and their Computation by Machine_ (Part
I)](http://www-formal.stanford.edu/jmc/recursive.html) (_Communications
of the ACM_, April 1960).  If you prefer a more "colorful" presentation,
I would recommend reading [Chapter
4](http://www.computingbook.org/Problems.pdf) and [Chatper
5](http://www.computingbook.org/Data.pdf) from a [highly-rated but
lowly-ranked and rarely-used introductory computing
textbook](http://www.amazon.com/Introduction-Computing-Explorations-Language-Machines/dp/1463687478/ref=cm_cmu_pg__header).
You should be able to translate the program examples from the Scheme
language used there into Rust.

Another interesting writing from John McCarthy is [_Progress and its
Sustainability_](http://www-formal.stanford.edu/jmc/progress/index.html).
Although, you might want to consider his predictive ability in light of
this one also: [_Networks Considered Harmful for Electronic
Mail_](http://www-formal.stanford.edu/jmc/harmful.html) (December 1989).

> _The reason why telefax will supplant email unless email is separated
> from special networks is that telefax works by using the existing
> telephone network directly. To become a telefax user, it is only
> necessary to buy a telefax machine for a price between $1,000 and
> $5,000 (depending on features) and to publicize one's fax number on
> stationery, on business cards and in telephone directories. Once this
> is done anyone in the world can communicate with you. No complicated
> network addresses and no politics to determine who is eligible to be
> on what network. Telefax is already much more widely used than email,
> and a Japanese industry estimate is that 5 percent of homes will have
> telefax by 1995 and 50 percent by 2010. This is with a $200 target
> price.  ...  More generally, suppose the same need can be met either
> by buying a product or subscribing to a service. If the costs are at
> all close, the people who sell the product win out over those selling
> the service. Why this is so I leave to psychologists, and experts in
> marketing, but I suppose it has to do with the fact that selling
> services requires continual selling to keep the customers, and this
> keeps the prices high.  I hope my pessimism about institutions is
> unwarranted, but I remember a quotation from John von Neumann to some
> effect like expecting institutions to behave rationally is like
> expecting heat to flow from a cold place to a hot place._

Were institutions more rational than John McCarthy predicted, or is there some other reason why his prediction was so wrong?

<div class="gap">
#
</div>

# Processes, Threads, and Tasks

What is difference between a process and thread?

<div class="gap">
#
</div>

Is a Rust task more like a process or a thread?

<div class="gap">
#
</div>

How can Rust tasks provide process-like memory isolation but without the expense of a traditional process?

<div class="gap">
#
</div>

\clearpage

## Spawning Tasks

The `spawn` function takes in an owned function (which cannot capture
any mutable, shared objects) and runs that function in a new thread:
````rust
    fn spawn(f: ~fn())
`````

These two constructs are equivalent (the second is preferred for
readability, but the first is better for understanding what you are doing):
```rust
spawn( | | {  
    println("Get back to work!"); 
});

do spawn {  
    println("Get back to work!”)");
}
````

Channels provide a way for spawned tasked to communicate back to their
parent:

````rust
   let (port, chan) : (Port<int>, Chan<int>) = stream();
   let val = node.head;
   do spawn {
      chan.send(f(val));
   }
   let newval = port.recv();
````

The `port.recv()` call with block until a sent value (from
`chan.send(f.val)`) arrives.


## Multi-Tasked Mapping

````rust
struct Node { head : int, tail : Option<~Node> }
type List = Option<~Node> ;

trait Map {
    fn mapr(&self, extern fn(int) -> int) -> List;
}

impl Map for List {
    fn mapr(&self, f: extern fn(int) -> int) -> List { 
         match(*self) {
            None => None,
            Some(ref node) => { 
                let (port, chan) : (Port<int>, Chan<int>) = stream();
                let val = node.head;
                do spawn {
                    let res = f(val);
                    chan.send(res);
                }
                let newtail = node.tail.mapr(f); // needs to move here!
                let newval = port.recv();
                Some(~Node{ head: newval, tail: newtail })
            }
        }
    }
}

fn collatz_steps(n: int) -> int {
    if n == 1 {
        0
    } else {
        1 + collatz_steps(if n % 2 == 0 { n / 2 } else { 3*n + 1 })
    }
}

fn find_collatz(k: int) -> int {
    // Returns the minimum value, n, with Collatz stopping time >= k.
    let mut n = 1;
    while collatz_steps(n) < k { n += 1; }
    n
}

````



# Modern Processors

For a much more entertaining answer to the question of why the best laptop I could buy at Cavalier Computers yesterday only has four cores, read 
James Mickens' [_The Slow Winter_](https://www.usenix.org/system/files/1309_14-17_mickens.pdf) (a hilarilous short essay, but with lots of big technical ideas in it)

> _Today, if a person uses a desktop or laptop, she is justifiably
angry if she discovers that her machine is doing a non-trivial
amount of work. If her hard disk is active for more than a second
per hour, or if her CPU utilization goes above 4%, she either
has a computer virus, or she made the disastrous decision to
run a Java program. Either way, it's not your fault: you brought
the fire down from Olympus, and the mortals do with it what
they will. But now, all the easy giants were dead, and John was
left to fight the ghosts that Schr&ouml;inger had left behind. "John,"
you say as you pour some eggnog, "did I ever tell you how I
implemented an out-of-order pipeline with David Hasselhoff
and Hulk Hogan's moustache colorist?"  You are suddenly aware
that you left your poncho in the other room._


