Recently e-mail came around at Agorics about 11:30. It included an URL to the internal server. Launching that URL led to a voting program where each recipient could vote for one of the restaurants that we go for lunch. It was a cute idea and I thought that I would implement the function in a multi user Scheme such as suggested by Rees. This is the code, without UI:
(define (mocntr) (let ((x 0)) (cons (lambda () (let ((yet #t))
(lambda () (if yet (begin (set! yet #f) (set! x (+ 1 x)) x)))))
(lambda () x))))
(define lunchcrowd (list (lambda (x) (write (cons "for Bill" x)))
(lambda (x) (write (cons "for Bob" x))
((cdr (assoc "Mandarin" (cdr x)))))))
(define restaurants (list "Mandarin" "Casa Lupe" "Coffee Shop"))
(define (noontime) (let ((bb
(map (lambda(r) (cons r (mocntr))) restaurants)))
(for-each (lambda (e) (e (cons "Lunchtime!" (map
(lambda(r)(cons (car r) ((cadr r)))) bb)))) lunchcrowd)
(lambda ()(map (lambda(x) (cons (car x) ((cddr x)))) bb))))
First a comment about the formatting: I don’t know how to format such programs to suit either myself or any current program æsthetics. To read my own code I must use an interactive editor that balances parentheses.

Top Down

Sometime before lunch most days some instigator issues the Scheme command (define res (noontime)). This sends a message to each member of the lunch crowd that solicits a vote on today’s restaurant choice. The form of this message is the Scheme value ("Lunchtime!" . (("Mandarin" . proc) ("Casa Lupe" . proc) ... )). To invoke a proc is to vote for the associated restaurant. A recipient may vote for more than one but may not vote for the same restaurant more than once. Code somewhere can produce the following image from this Scheme value:
Casa Lupe
Coffee Shop
The buttons invoke the corresponding proc. These ideas do nothing to address the dilemma of who chooses and provides the presentation. The blind user would better with the raw message.

When it is time to decide the Scheme command (res) from the instigator’s terminal, reports the results of the voting.

The code above is fake in that the procs in lunchcrowd would in practice be constructed by the various diners and somehow those procs would invoke the eater and not merely some caned procedure. Bob, on the other hand, seems to have cast a permanent vote for Mandarin. This illustrates that much of the rest of the code actually runs!

Code Explanation

An invocation of mocntr is made each day for each restaurant. It returns a source of options, one of which will be offered to each of the lunch crowd. The second lambda in the definition produces such an option. The variable yet in that proc remembers if the option has been taken. The third lambda produces the getter for the count.

bb is created each day for lunch and constitutes the ballot box. It is a list of pairs <restuarant name, <option source, count getter>>. This list is iterated over first to send each vote solicitation, and then later to count the votes.

Running the above code

((noontime)) => ("for Bill" "Lunchtime!" ("Mandarin" . #) ("Casa Lupe" . #) ("Coffee Shop" . #))
("for Bob" "Lunchtime!" ("Mandarin" . #) ("Casa Lupe" . #) ("Coffee Shop" . #))

(("Mandarin" . 1) ("Casa Lupe" . 0) ("Coffee Shop" . 0))
The code as it stands solicits a vote only after it records the previous vote—serial voting.
Scheme needs to address concurrency and to support atomic actions such as (set! x (+ 1 x)). The language Actors does all of this nicely I think but I have no implementation of Actors. I suppose that Java can do this but with much more ocde.

Lessons for Keykos or Eros

It would be nice if there were a way to do such things with so little code.

This shows problems with garbage collection that are germane to an OS. If one of the lunch crowd is away for several days his options persist for no purpose. In Keykos and I presume Eros, the instigator can reclaim all space after they are back from lunch, even though there may remain references.