Homework 4. Side-effect-free light-weight processes in Scheme

Motivation

The lwp-list example in Dybvig §3.3 is unsatisfying. It has a global variable lwp-list and all the procedures that it defines access and/or modify this global variable. From a pure functional-programming standpoint, it would be better to remove the global variable lwp-list. This could be done by modifying each procedure that examines the list of light-weight processes to instead accept the list as an argument, and by modifying each procedure that sets the list to instead return the new list.

Assignment

Modify the example code, removing all uses of set! and avoiding the use any other side effects. You will need to modify the API for the procedures as described above. Other than the API change, the modified procedures can make the same assumptions about the light-weight process list that the original code does.

Add a procedure exit-lwp that causes the calling light-weight process to exit. Other light-weight processes continue executing.

Your exit-lwp procedure can assume that at least one light-weight process continues executing after the calling one exits: that is, it need not worry about the case where all light-weight processes exit. However, you should also look into the problem of writing a side-effect-free implementation of exit-lwp that works as expected when all light-weight processes exit.

To turn in your assignment, submit a file hw4.scm containing your definitions of start, pause, exit-lwp, and any other auxiliary definitions. The first line of hw4.scm should be a comment containing your name and student ID.

If you successfully implemented a a side-effect-free version of of exit-lwp that works as expected when all light-weight processes exit, call it exit-lwp0 and submit it as part of hw4.scm.

Also submit a brief ASCII text file hw4.txt explaining the problems you found when you attempted to write exit-lwp0. If you were successful, explain how; if not, explain what you would need to become successful.

Make sure that your code works with the MzScheme installation on SEASnet.

Example

(define lwp1
  (lambda (ps) (let f ((ps ps) (n 4))
                 (if (zero? n)
                     (exit-lwp ps)
                     (begin
                       (display "a") (display n)
                       (let ((ps1 (pause ps)))
                         (display "A") (display n)
                         (f (pause ps1) (- n 1))))))))
(define lwp2
  (lambda (ps) (let f ((ps ps))
                 (display "g")
                 (f (pause ps)))))
(define lwp3
  (lambda (ps)
    (display "G")
    (let ((ps1 (pause ps)))
      (display "H") (exit-lwp ps1))))

(define lwp4
  (lambda (ps) (let f ((ps ps))
                 (display "t")
                 (f (pause ps)))))

(define lwp5
  (lambda (ps) (let f ((ps ps))
                 (newline)
                 (f (pause ps)))))

(define lwp6
  (lambda (ps) (let f ((ps ps) (n 9))
                 (if (zero? n)
                     (exit-lwp ps)
                     (begin
                       (display "q") (display n)
                       (f (pause ps) (- n 1)))))))

Given the above definitions, then the expression:

(start (list lwp1 lwp2 lwp3 lwp4 lwp5 lwp6))

should generate the following never-ending output:

a4gGt
q9A4gHt
q8a3gt
q7A3gt
q6a2gt
q5A2gt
q4a1gt
q3A1gt
q2gt
q1gt
gt
gt
gt
gt
gt
…

© 2003, 2004 Paul Eggert. See copying rules.
$Id: hw4.html,v 1.18 2004/10/23 10:10:25 eggert Exp $