Re: Metaclass & McCLIM revisited
"Paul Werkowski (as pw at snoopy dot qozzy dot com)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
LW's CLIM was the reason I invested personal money to buy LispWorks Pro many years ago, when it was still HCL, for work. Mike MacDonald starting McCLIM got me interested. Now, retired, I use the Hobbiest edition which does not include CLIM. On 1/29/2026 2:14 PM, Alexey Veretennikov wrote: > Hi, > > Very interesting. What advantage the McCLIM has over the LW's own proprietary CLIM? Couldnt with LW Pro one get the CLIM for less efforts (in time/money) than to properly convert McCLIM to LW? > > > BR, > /Alexey > > Sent from Proton Mail for Android. > > -------- Original Message -------- > On Thursday, 01/29/26 at 19:16 Paul Werkowski (as pw at snoopy dot qozzy dot com) <[email protected]> wrote: > Back in May I wrote that the new release of open source CLIM, McCLIM, > failed to compile on Lispworks. > The main problem was the inclusion in the source code a new file, > dynamic-vars.lisp, which introduced a CLOS class with a non standard > metaclass, CLASS-WITH-DYNAMIC-SLOTS. > This was to implement an object slot scheme in which the slot-value of > specified slots were initialized to be an instance of class > DYNAMIC-VARIABLE which would contain the actual value of interest. The > idea being that cl:slot-value and (setf slot-value) would access > (dynamic-variable-value object slot-name), not the container instance. > All of this to support the concept of thread-local slots. An instance of > class TLS-RECORD-CONTEXT would contain graphic context info needed by > the graphics backend for drawing to screen. > > It seemed that LispWorks could not deal with that metaclass stuff. It > was suggested to me by the author of that code that LispWorks's > implementation of the ANSI MetaObject Protocol was somehow deficient. > > I decided to find out what it would take to get that system to work in > LispWorks. I began by chasing symptoms. The issues encountered were: > > * 1. Slot Initialization. > * 2. Slot-value customization via slot-value-using-class. > * 3. Automatic slot-accessor generation. > > The first was very puzzling, the second easy. The third at first crazy > but finally interesting. > > So I came up with something that worked. McCLIM compiled and worked > properly as before. Tread-Local slots worked as designed. > > I was not at all pleased with the results. The name of old Rube Goldberg > and his wacky inventions came to my mind. Nested > ENSURE-CLASS-USING-CLASS :AFTER methods, first to insert the metaclass > name as an explicit superclass to a user class in order to get > initialize-instance to be called, then creating a new class metaobject > after removing slot accessor methods and then re-installing new methods, > all to supress anoying method redefinition warnings. > > I decided I needed to take a break for awhile and went off to visit an > old friend, CMUCL. In 1994, I spent four or five months of nights and > weekends finishing the port from RISC workstations to x86 CISC PC > running on FreeBSD Unix. That effort eventually led to a fork resulting > in SBCL. This time I assisted current cmucl maintainers attempting to > get McCLIM running on that CL. > > So, the result of all that is: there is nothing deficient with > LispWorks' CLOS. All(?) the free CL implentations use Portable Common > Loops (PCL) for an object system. PCL was created by Xerox cica 1986 and > was one of several lisp object system to influence the CLOS of the ANSI > spec, a predecessor to or prototype of CLOS. The "closer-mop" quicklisp > package tries to bridge the difference. What I remember most of PCL in > the 90's is that it took about 4 hours to compile on my minimally > configured 486 PC. > > McCLIM is only portable among Lisps that use PCL for an object system. > > ------ > What's the difference between PCL and LW CLOS? > > Start at the beginning with object initialization. The DV code starts > with CL:ALLOCATE-INSTANCE. > > From CLHS, > "The generic function allocate-instance creates and returns a new > instance of the class, without initializing it. When the class is a > standard class, this means that the slots are unbound; when the class is > a structure class, this means the slots' values are unspecified." > > Also, > " The consequences of adding methods to allocate-instance is > unspecified. This capability might be added by the Metaobject Protocol." > > The DV code (written for PCL) uses generic-function > cl:allocate-instance, specialized to the metaclass > (class-with-dynamic-slots), to install instances of Dynamic-Variable in > specified slots. Lispworks executes that code and then ensures the slots > are unbound. > > So, what to do? First thought was to move that code to > initialize-instance :after only to find that initialize-instance was not > called at all by LW (or PCL). Apparently, I-I is a thing that only > metaclasses STANDARD-CLASS and STRUCTURE-CLASS know about. I found that > installing the metaclass name as an explicit superclass, eg. (defclass > myclass (class-with-dynamic-slots) ...) got past that obstacle. > > More correct is to use MAKE-INSTANCE specialized to the metaclass name. > A bonus here is that on entry to make-instance, default and specified > :intargs have been resolved and all that is needed is to insert those > values into a new DV instance and install that in the slot. > > Second, SLOT-VALUE. > > The CLOS spec suggest implementations have function SLOT-VALUE call GF > SLOT-VALUE-USING-CLASS. PCL does this for the function and also for > default accessor methods specified in DEFCLASS slots. PCL's > slot-value-using-class expects the second argument to be a > SLOT-DEFINITION metaobject. LispWorks second argument to slot-value is > slot-name (a symbol), and uses CLOS::STANDARD-INSTANCE-ACCESS or > (CLOS::FAST-STANDARD-INSTANCE-ACCESS) for both slot-value and default > acccessor methods. Thus slot-value of a DV slot picks up the DV instance > instead of its imbedded value. Closer-mop arranges to find the proper > slot-definition metaobject by name and passes that to > slot-value-using-class. > > Third, Slot Accessor Methods. > > So, how to get those optimized accessor methods to do the right thing. > It turns out that LW's CLOS has the MOPery to do that. > CLOS:READER-METHOD-CLASS, CLOS:MAKE-READER-METHOD, > CLOS:WRITER-METHOD-CLASS and CLOS:MAKE-WRITER-METHOD do the job. > > A downside is that a few things neither documented nor exported from > :CLOS are needed. > > Finally, attached is build-mcclim.lisp which, when loaded, generates an > environment and and a function of that name that will (with a bit of > luck) fetch (via quicklisp) all the needed software, compile, load and > patch McCLIM and optionally the clim demo/examples system. > This presents a table of 68 push-buttons, each of which will produce a > possibly interactive graphic. All but the last three, starting with the > word 'concurrent', appear to work. There is also a test suite, > "mcclim/test" with results: > > Did 2200 checks. > Pass: 2191 (99%) > Skip: 0 ( 0%) > Fail: 9 ( 0%) > > NOTE! A working X11 server must be installed. I use "VcXsrv X Server" on > Windows 10 which can be obtained from vcxsrv.sourceforge.net. > > _______________________________________________ Lisp Hug - the mailing list for LispWorks users [email protected] http://www.lispworks.com/support/lisp-hug.html