Have you run any benchmarks for this? It seems an extremely
heavyweight operation for something which should be very
lightweight. The dependence on dynamic-wind also means
performance will be highly variable per implementation.
The sample implementation won't perform well on implementations, for which call/cc is costly due to the presence of dynamic-wind. While I don't think that a Scheme implementation for which one of Scheme's main selling points is too slow to be used effectively is, in my opinion, a very decent one, I could change the sample implementation not to rely on call/cc in most use cases of forcing.
I could define a parameter object that holds a value representing the current dynamic environment (or dynamic extent, see above). Then I would have to setup and restore this parameter object at every use of dynamic-wind and parameterize. When a promised is forced, one can then take a short route if the current dynamic environment is the same as the one of the promise, which is testable by using the parameter object.
For a Scheme implementor I would propose to use a method like this one; for the sample implementation it is less attractive because one would have to import dynamic-wind and parameterize from the sample implementation and not from (scheme base) to make the customized versions of dynamic-wind and parameterize work.
That said, I think one has to be very careful when arguing with the performance of current implementations. If one had done this in the past, Scheme probably would not have lexical bindings (apparently, there were days when it was assumed to be too costly when compared to dynamic bindings), or closures, or call/cc. Haskell would have not be a lazy programming language, and so on.
If we want to see Scheme showing the world the future of programming languages again, it won't help us to always take the lowest common denominator of all existing interesting implementations.
Anyway, the implementation method described above should provide a lightweight means for the "functional" promises of this SRFI and should not be hard to implement in an existing implementation, even if the implementation method is hard to achieve in the portable sample implementation (without having to override core Scheme procedures).
Note I think delay-force/lazy were a mistake. Their semantics
are of course desired, but I think in retrospect it's sufficient to
require (delay (force x)) be statically detected and the same
guarantees made - this can be done portably.
Why do you think it was a mistake? The power of the language is exactly the same - whether you write (delay (force ...)) or (delay-force ...). The only difference seems to me that (scheme lazy) would pollute the namespace by one identifier less.
Or do you think that we would not have to tell users of Scheme to write "delay-force" instead of "(delay (force ...))" because the Scheme system would take care of that itself?
In any case, an implementation of (scheme lazy) is free to write:
(define-syntax delay
(syntax-rules (force)
((delay (force x))
(delay-force x))
((delay x)
...)))
If you want, I can make this mandatory for the delay as exported by SRFI 155. Yes, maybe that's a good idea.
--
Marc
To unsubscribe from this list please go to http://www.simplelists.com/confirm.php?u=3gmIi49Ouh6YpCluDZXWeokz7NgY9f9r