quoth Christian:
(Note that the "limit" is not actually limiting any calculation (assuming that futures do terminate); it's just making other futures wait until earlier ones are done. You'll want this when starting external tools, otherwise you'll make your machine's responsitivity suffer.)
yeah, I'm not actually calling external processes. However, my instinct is to still have gambit catch the appropriate exceptions, and go until it runs out of memory or filehandles or processes, or whatever. Typically I set the limits from the outside with a ulimit command before I start the process, giving me a unified interface, and confidence that the limits will be respected. Also makes gambit graceful if you need to scale it down, and run in an evironment with few resources.
From a unix perspective, I think external limits and graceful failure
are the right thing to do.
The name |fn!| in (define (make-reporting-thread fn! . timeout) ..) looks funny: fn is normally used for "function", and (pure) functions don't have side effects. |proc| might be a better name. But actually I'm not sure what it does. (Well I see that it's return value isn't used at all.)
That's it. it's passed to for-each, meaning it's "called for it's side-effects", as R5RS says.
What does make-lazy do? It can't just be an alternative implementation of a make-promise, since those would take a thunk, not an 1-ary function.
ah, right, it does this:
(define (make-lazy fn) (define (me) (delay (call/cc (lambda (exit) (cons (fn (lambda () (exit '()))) (me)))))) (me))
i.e., the fn creates the car part of a nearly infinite series, and can conditionally call the exit thunk to escape the cons & terminate the stream.
That seemed like the right way to do it.
So, overall, it folds over the stream, creating a thread for each element which sends it's result to the mailbox of the reporting thread. The fold counts the number of elements in the stream, and assigns the reporter's specific field that total number. the reporter loops over it's mailbox until it's counted as high as it's specific field, and then it exits.
the primoridal thread join!'s the reporter with a timeout, so that if a thread or two hang for a long period of time, I'll ignore them and quit anyway.
Lang