Re: strict promises? Andre van Tonder 08 Feb 2004 17:42 UTC

On Sat, 31 Jan 2004 xxxxxx@bloodandcoffee.net wrote:

> I just found myself wanting to create a promise, but not to delay its
> evaluation.  I could do
>
>   (let ((p (delay <expression>)))
>     (force p)
>     p)
>
> but that would needlessly compute and complicate.  STRICT would do just
> what I want.  Why was STRICT not provided in the first place, in fact?

True.  For example, it is inefficient to write things like
  (delay '())
  (delay 1)
  (delay x)
when the argument is self-evaluating or a variable.  The primitive
*strict* as in the orginal version of the SRFI would solve this problem.

On the other hand, *strict* does complicate the interface and, as you
note, can be simulated (observationally) using the other primitives.  In
this sense, a minimal basis is given either by
  {strict, lazy, force} with (delay e) = (lazy (strict e)) or
  {delay, lazy, force} with (strict e) = (let ((x e)) (delay x)).

I see the following possible options:

1) Follow R5RS precedent and don't bother to address this.

2) Provide all four {lazy, strict, delay, force}.
   In this case,
   I am not sure that *strict* is the right word - it has the same
   signature as *delay* and should really be a verb, with meaning
   "doing something right away" (expedite?, discharge?, rush?)

3) Make it an optimization issue:  In other words, keep the interface
   as it is now {lazy, delay, force}  but special-case the *delay* macro
   such that
     (delay e)       = (cons 'value e) when e atomic (literal or variable)
     (delay (quote e)) = (cons 'value (quote e))
   This would make the above examples efficient, and would make *strict*
   definable as (strict e) = (let ((x e)) (delay x)) if
   someone should need it for arbitrary expressions.

My preference is for (3).  My feeling is that
the interface should not be complicated by optimization issues that
can be handled under the hood.  But I may be overlooking something so let
me know what you think.

Regards
Andre