
- low-level API: remove_task

- Cores: use pipes instead of local files (and thus select instead of wait)
  and compare performances

- Cores: flush stdout and stderr before fork, to avoid duplicating
  user messages

- more fault tolerance:

  master should not be blocked when sending a huge data to a worker
  which is not reading (e.g. the worker is suspended or unreachable)

  solution: instead of using Unix.write which behaves as an atomic
  operation (possibly blocking), write our own loop using select with
  a timeout; when it timeouts, close the connection to that worker

- try Mandelbrot with Same

- make an experiment with different OS

- check consistency of executables (md5 checksum)

- acknowledgment for killed message: use Aborted for that purpose

- minimal API (map, fold, etc.)

  . map : ...

  . reduce : (a -> b) -> (c -> b -> c) -> c -> a list -> c

    assumption : the order of elements in the list is irrelevant
    variants   : local/remote reduce

  . reduce2 : (a -> b) -> (b -> b -> b) -> b -> a list -> b list

    assumption : reduce is AC
    variant    : reduce is A but not C
                 (still we can parallelize some adjacent reductions)

- make Str generic wrt a type t together with 2 functions to/from_string

- refactor map, etc. in Cores/Network

- make the master more robust [fault tolerance]
  - pinging workers (a separate list for not responding workers)
  - (re-)scheduling heuristics

- how to change the port number (either Control.set_port / environment variable)

BUGS ?

- using localhost as a worker

- do we need to shutdown sockets eventually?
  (currently we don't do it, because we don't know when to do it,
  unless we are using at_exit --- but we can't use at_exit!)
