Subject: Re: Dynamic function bindings
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 21 Jan 2006 21:49:10 -0600
Newsgroups: comp.lang.lisp
Message-ID: <VYWdnY2PmagrnU7enZ2dnUVZ_tudnZ2d@speakeasy.net>
Marcin 'Qrczak' Kowalczyk  <qrczak@knm.org.pl> wrote:
+---------------
| 4. The consensus of Common Lisp threading systems is that newly
|    created threads use global bindings of dynamic variables instead of
|    inheriting bindings from the place of creation of the new thread.
+---------------

Wow! One learns something new every day! I would have thought the
"natural" way would be to inherit the same thread-local variables,
but CMUCL seems to agree with you:

    > (defvar *x* 3)

    *X*
    u> (defun x () (format t "~&*X* = ~s~%" *X*))

    X
    > (x)
    *X* = 3
    NIL
    > (let ((*x* 17))
	(flet ((pfunc () (sleep 5) (x)))
	  (mp:make-process #'pfunc)))

    #<Process Anonymous {488E00BD}>
    >
    *X* = 3		<-- Printed asynchronously

Looking further at MAKE-PROCESS, I discovered that it provides a
separate explicit keyword argument to set any desired "extra"
special bindings for the new thread, which are indeed private
to the thread:

    > (let ((*x* 17))
	(flet ((pfunc () (sleep 5) (x)))
	  (mp:make-process #'pfunc :initial-bindings '((*x* . 29)))
	  (sleep 1)
	  (x)))

    *X* = 17
    NIL
    > (x)	; manually typed

    *X* = 3
    NIL
    > 
    *X* = 29		<-- Printed asynchronously

Do any of the old-timers have any history to share on why it was
chosen to work this way?


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607