Kelly Murray <kem@IntelliMarket.Com> wrote:
| Scheme has a similiar concept called "promises"...
| ...one must FORCE the values before calling FOOBAR.
| [unless FOOBAR itself was recoded to call FORCE.]
| (foobar (force (promise (zip 1))) (force (promise (zap 2))))
| The astute reader will notice this code in fact will not
| execute in parallel at all, because the call to FORCE will
| immediately wait for the computation to finish, and thus
| the ZIP call must complete before the ZAP call is invoked
| as a promise, which also is immediately waited for.
| The "fix" is to use a let to get the two processing running
| before forcing them:
| (let ((zip-1 (promise (zip 1)))
| (zap-2 (promise (zap 2))))
| (foobar (force zip-1) (force zap-2)))
| But unfortunately, this results in only TWO parallel operations,
| because the force call on zip-1 causes the current process to
| immediately wait for zip-1 to complete.
But this is not how promises are intended to be used in Scheme.
Instead, it is expected that you *will* "recode FOOBAR" to pass
the promises down un-forced:
(foobar (promise (zip 1)) (promise (zap 2)))
and that only where the value of an argument is actually needed would
the "force" eventually be done (if ever).
The downside (from a "futures" or "lazy-eval" sperspective) is that
everyone from "foobar" all the way down has to understand that any
given value might be a promise, and force it when necessary. Though
[as the standard explicitly permits] partial relief from this odium
can be gotten from:
- Implementations which allow "force" to be the identity operator
when applied to non-promises;
- Implementations which implement "implied forcing" in primitives;
- Or simply use (define (force-if-needed x) (if (promise? x) (force x) x)).
Yes, it's "uglier" than futures, but not as disfunctional as you claim.
Rob Warnock, 8L-855 email@example.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
2011 N. Shoreline Blvd. FAX: 650-964-0811
Mountain View, CA 94043 PP-ASEL-IA