Re: clos mop

"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]>
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
In fact, I think this is how GP and CAPI actually work…



> On Mar 31, 2025, at 13:04, David McClain (as dbm at refined-audiometrics dot com) <[email protected]> wrote:
> 
> Ooh! I like the idea of the PROGV. I’ve never done much with PROGV and now I see how it can be useful.
> 
> Not picking on you, but in the graphics example, where some portion of the graphics state is shared across all threads, and details like pen color and graphics transforms on the shared state is thread local, then why not just keep the constant portion in a shared immutable state (M of them), and all the TLS stuff in a separate dynamically bound struct or instance? 
> 
> Sounds like a matter of proper data factoring.
> 
>> On Mar 31, 2025, at 12:43, Daniel Kochmański <[email protected]> wrote:
>> 
>> If a dynamic variable is sufficient, then it is clearly better. Now cConsider that you have a a class BUFFER with a slot CURRENT-LINE and many instances of that class. How do you make the current line of each buffer thread-local?
>> 
>> Another example is that you have some drawing options, like an ink and a current transformation used when drawing on a window - also stored as slots in a medium. If you had wanted to rely on dynamic variables, you'd be forced to have NxM of them, where N stands for number of slots and M stands for number of instances.
>> 
>> You can of course make symbols dynamically and bind them with PROGV and conceptually this is similar, where the symbol is stored in the slot and the value is read using this symbol's dynamic value.
>> 
>> Best regards,
>> Daniel
>> 
>> 
>> 
>> --
>> Daniel Kochmański ;; aka jackdaniel | Przemyśl, Poland
>> TurtleWare - Daniel Kochmański      | www.turtleware.eu
>> 
>> "Be the change that you wish to see in the world." - Mahatma Gandhi
>> 
>> 
>> 
>> On Monday, March 31st, 2025 at 9:35 PM, David McClain <[email protected]> wrote:
>> 
>>> Very interesting approach…
>>> 
>>> But I have found that simply using a dynamic variable, as with DEFVAR or DEFPARAMETER, does everything you could need by using TLS. Just have the executing thread perform a dynamic binding to the global var using LET and be done. At the start, all threads see the same global value. But after LET, the running thread inside the scope of the LET has its own value, while all other threads continue to see the default global value. Each thread can do this for itself.
>>> 
>>> So, where is the advantage to declaring an explicit :TLS on a slot?
>>> 
>>> - DM
>>> 
>>>> On Mar 31, 2025, at 10:22, Paul Werkowski (as pw at snoopy dot qozzy dot com) [email protected] wrote:
>>>> 
>>>> I've known about the MOP ever since I bought Kickzales et al "The Art of the Metaobject Protocol" in 1992 or so, and even read some of it, but never had any opportunity to use it or even seen an example of its use. Now I have.
>>>> 
>>>> At https://turtleware.eu/tag/mop.html there are three articles on Dynamic-Variables that make heavy use of the MOP. The author of these posts, Daniel Kochmanski, aka jackdaniels, aka jd, is also the most active contributor to the McCLIM project for the past few years and has recently tagged the repo with its second release ,"OSTRA", which has Dynamic-Variables integrated into its core. Apparently the major use of DVs is to implement thread-safe drawing to screen.
>>>> 
>>>> I've been following McCLIM development since Mike MacDonald started it over 20 years ago and have been working on an experimental CAPI backend for it for a year or so.
>>>> 
>>>> McCLIM now is entirely broken on LispWorks. The culprit appears to be DVs. Daniel says all is well using SBCL and other open source CL and believes something is wrong with Lispworks MOP. I have a seldom used installation of SBCL with Emacs & Slime available. I have now tested Dynamic-Vars.lisp (which can be downloaded from the McCLIM repo on codeberg.org in the folder mcclim/core/system/ ) on SBCL, and yes, work fine!
>>>> 
>>>> I now have discovered how to get DVs working on LWW 8.1 but not without modifying code. See below.
>>>> 
>>>> DVs are pretty interesting in their own right. Consider a class (as documented in the posts)
>>>> 
>>>> (defclass C1 ()
>>>> ((slot1 :initarg :slot1 :dynamic nil :accessor slot1)
>>>> (slot2 :initarg :slot2 :dynamic t :accessor slot2)
>>>> (slot3 :initarg :slot3 :dynamic :tls :accessor slot3))
>>>> (:metaclass class-with-dynamic-slots))
>>>> 
>>>> Slot3 is a thread-local-slot. An instance of C1 can be shared among several threads with slot3 being unique to each thread. Other uses are described in the posts.
>>>> Also, according to jd, use of DV's is transparent (but not with LW).
>>>> 
>>>> So, it appears the SBCL's implementation of C::SLOT-VALUE is significantly different from LW's.
>>>> 
>>>> My work-around is to use MACROLET to shadow cl:slot-value as shown in the attached file. The function test-dv4 contains some portions of a test suit (ql:quickload "mcclim/test") that now work fine when modified using these forms.
>>>> 
>>>> (defmacro with-dynamic-slots* (&body body)
>>>> `(macrolet ((slot-value (o s)`(dynamic-slot-value ,o ,s)))
>>>> (progn ,@body)))
>>>> 
>>>> (defmacro with-dynamic-slots (slotnames form &body body)
>>>> `(macrolet ((slot-value (o s)`(dynamic-slot-value ,o ,s)))
>>>> (with-slots ,slotnames ,form
>>>> ,@body)))
>>>> 
>>>> I also needed an iniitialize-instance :around method to handle :initargs and still need to add code somewhere to add :accessor methods.
>>>> 
>>>> I thought that LW's DEFADVICE facility might work for slot-value, but the manual discourages using it for low level functions. Trying to mess with changing slot-value directly was clearly foolish!
>>>> 
>>>> SBCL was very unhappy with me messing with shadowing its slot-value warning loudly about violating PACKAGE-LOCK protocols.
>>>> 
>>>> So, Common-Lisp's goal was to minimize such difference of result. What does anyone think is going on?
>>>> 
>>>> Paul
>>>> 
>>>> <dv.lisp>
> 
> 
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> [email protected]
> http://www.lispworks.com/support/lisp-hug.html


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.