[Openmcl-devel] Thread-local bindings

Ron Garret ron at flownet.com
Fri Jun 14 09:18:52 PDT 2019


You might want to read this:

http://www.flownet.com/ron/specials.pdf

and particularly the section called “the pervasiveness of defvar”.

Also: instead of running your code at the top level, try putting it inside a function and calling the function before and after the DEFVAR.  You will see the different results.  The thing that is surprising you is happening at compile time.

rg

On Jun 14, 2019, at 9:14 AM, Rainer Joswig <joswig at lisp.de> wrote:

> If a variable is used in a function and there is no special declaration and there is no DEFVAR, then the binding is lexical.
> 
> DEFVAR declares a variable to be special.
> 
> Then ALL new code on all levels (all lets, lambda vars, ...) will use dynamic binding.
> 
> 
> 
>> Am 14.06.2019 um 16:16 schrieb martin <brooks.martin at sympatico.ca>:
>> 
>> Hello All
>> 
>> I am confused about the semantics of thread-local bindings when using process-run-function. 
>> CCL version: Clozure Common Lisp Version 1.12-dev (v1.12-dev.4-3-gdd5622e9) DarwinX8664
>> 
>> Suppose that the variable foo is not globally bound:
>> 
>> ? foo
>> > Error: Unbound variable: FOO
>> 
>> Consider the following form:
>> 
>> (process-run-function :process1 
>>   #'(lambda ()
>>       (let ((foo 2))
>>         (flet ((bar () (print foo) :return-me-from-foo))
>>           (bar)
>>           (process-run-function :process2 #'bar)
>>           :return-me-from-lambda))))
>> 
>> The result is to print 2 twice:
>> 
>> 2 
>> 2 
>> 
>> Neither keyword return value appears, nor should they — I put them in the code to disambiguate printing from the value returned by print.
>> 
>> Now bind foo at top level.
>> 
>> ? (defvar foo 3)
>> FOO
>> 
>> Execute the form again, to get these to print results:
>> 
>> 2 
>> 3 
>> 
>> My confusion: 
>> The second result (print 2 & 3) demonstrates my understanding of thread-local bindings.
>> The first result (print 2 & 2) seems wrong — why didn’t Lisp complain that foo was unbound in the call to bar within :process2 ?
> 
> Because FOO uses the lexical binding introduced by the LET.
> 
>> 
>> My confusion gets worse — restart Lisp, so that foo is not globally bound, and do the same tests with the following form, to see it print 4 & 4.
>> 
>> (let ((foo 4))
>>   (process-run-function :process1 
>>     #'(lambda ()
>>         (flet ((bar () (print foo) :return-me-from-foo))
>>           (bar)
>>           (process-run-function :process2 #'bar)
>>           :return-me-from-lambda))))
>> 
>> 4 
>> 4 
>> 
> 
> 
> lexical binding
> 
> 
>> And now globally bind foo:
>> 
>> ? (defvar foo 5)
>> FOO
> 
> 
>> 
>> The form now prints 5 & 5 .
>> 
>> 5 
>> 5
>> 
> 
> dynamic binding
> 
> 
>> Help! What’s the rule?!?
>> 
>> Furthermore, I take it that stack-local bindings apply to variables only, not functions.
>> To test this, I gave bar a global definition:
>> 
>> (defun bar () (print 27))
>> 
>> But this did not change the above results; in other words, the local definition was used in both threads.
>> 
>> All consolation gratefully accepted,
>> Martin
>> 
>> 
>> 
>> 
>> 
>> 
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> https://lists.clozure.com/mailman/listinfo/openmcl-devel
> 
> _______________________________________________
> 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/20190614/28394fa2/attachment.htm>


More information about the Openmcl-devel mailing list