[Openmcl-devel] Thread-local bindings
martin
brooks.martin at sympatico.ca
Sat Jun 15 06:43:54 PDT 2019
Thank you Robert for your examples.
I take Ron’s point that closures are consistent in all usage, including funcall vs process-run-function.
I now understand is that “thread-local binding” means that process-run-function is executed in the top-level environment.
— “Dynamic extent” refers to time within a single thread, and does have meaning across multiple threads.
— Funcall is a function; process-run-function is a special form.
(let ((foo 4))
(declare (special foo))
(flet ((bar () (print foo) :return-me-from-bar))
(funcall #'bar)))
4
:RETURN-ME-FROM-BAR
(let ((foo 4))
(declare (special foo))
(flet ((bar () (print foo) :return-me-from-bar))
(process-run-function :process2 #'bar)))
> Error: Unbound variable: FOO
> While executing: BAR, in process PROCESS2(2).
> On Jun 15, 2019, at 1:28 AM, Robert Munyer <2420506348 at munyer.com> wrote:
>
> 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
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> https://lists.clozure.com/mailman/listinfo/openmcl-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20190615/3b4a21c9/attachment.htm>
More information about the Openmcl-devel
mailing list