[Openmcl-devel] Thread-local bindings

Robert Munyer 2420506348 at munyer.com
Fri Jun 14 22:28:28 PDT 2019


None of your results really involve thread semantics.
You can get all of those results with a single thread.
I will paste a transcript below.

martin wrote: 

> Actually, I am amazed that the closed-over case works.
> In the following form, process1 terminates before process2 calls bar;
> nevertheless the call to bar has access to the lexical environment of
> process1 - or maybe that isn't a correct description.
>
> (process-run-function :process1
>   #'(lambda ()
>       (let ((foo 4))
>         (flet ((bar () (print foo) :return-me-from-bar))
>           (bar)
>           (process-run-function :process2 #'(lambda ()
>                                               (sleep 10)
>                                               (bar)
>                                               :return-me-from-lambda))))))

It would be better to say that BAR has access to its _own_ lexical
environment, because it is a closure.  You can see the same thing
happening in several of my single-threaded replications below.

They would have failed in some early versions of Lisp, which
suffered from the "upward funarg problem", but Common Lisp
implementations are not allowed to have that problem.

See AI Memo #199, "The Function of FUNCTION in LISP, or Why the
FUNARG Problem Should be Called the Environment Problem".

Transcript replicating your results in standard CL, no threads:

? (defun bar () (print 27))
BAR
? (funcall (let ((foo 2))
             (flet ((bar () (format t "~&~s" foo)))
               (bar)
               #'bar)))
2
2
NIL
? (defvar *foo* 3)
*FOO*
? (funcall (let ((*foo* 2))
             (flet ((bar () (format t "~&~s" *foo*)))
               (bar)
               #'bar)))
2
3
NIL
? (funcall (funcall (let ((foo 4))
                      (lambda ()
                        (flet ((bar () (format t "~&~s" foo)))
                          (bar)
                          #'bar)))))
4
4
NIL
? (defparameter *foo* 5)
*FOO*
? (funcall (funcall (let ((*foo* 4))
                      (lambda ()
                        (flet ((bar () (format t "~&~s" *foo*)))
                          (bar)
                          #'bar)))))
5
5
NIL
? (funcall (let ((foo 4))
             (declare (special foo))
             (flet ((bar () (format t "~&~s" foo)))
               (bar)
               #'bar)))
4
> Error: Unbound variable: FOO
> While executing: BAR, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > :pop

? (funcall (let ((foo 4))
             (flet ((bar () (format t "~&~s" foo)))
               (bar)
               (lambda ()
                 (sleep 10)
                 (bar)))))
4
4
NIL



More information about the Openmcl-devel mailing list