Picolisp'ers,

As the subject asks, is it possible to return multiple distinct closures from a
single function? I was trying out a simple lazy lists implementation. The lazy
function takes in something and returns that something wrapped in another
function. If you want to 'force' the lazy value, you execute the wrapped
function.

The closure is needed to ensure that when you force a value more than once, the
wrapped function only gets executed the first time (and the cached value is used
thereafter).

So:

(de lazy @Bdy
  (fill
    '(job '((forced? . NIL)
            (value . "delayed"))
       (unless forced?
         (setq value (eval (car '@Bdy)))
         (setq forced? T))
       value)))

(de force (Lz)
  (eval Lz))

Pretty simple stuff, but it doesn't work as intended. The closure returned by
'lazy' is the same job closure for ALL invocations of lazy.

(setq foo (lazy
            (prog
              (prinl "!")
              2)))

(setq bar (lazy
            (prog
              (prinl "!!")
              3)))


pico λ: (force foo)
!
-> 2
pico λ: (force foo)
-> 2
pico λ: (pretty bar)
(job '((forced? . T) (value . 2))
   (unless forced?
      (setq
         value (eval (car '((prog (prinl "!!") 3)))) )
      (setq forced? T) )
   value )-> ")"
pico λ: (force bar)
-> 2

Is this an artifact of how 'job' works, by rewriting the internal definition of
the function which contains the call to job? How can one return distinct
*different* closures from a single function?

Returning a properly formed anonymous function (as opposed to a 'job' form)
doesn't make a difference:

(de lazy2 @Bdy
  (fill
    '(()
      (job '((forced? . NIL)
             (value . "delayed"))
        (unless forced?
          (setq value (eval (car '@Bdy)))
          (setq forced? T))
        value))))

(de force2 (Lz)
  (Lz))

--
Regards,
       Imran Rafique
--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to