From piotr.wasik at gmail.com Sat Nov 2 21:03:06 2013 From: piotr.wasik at gmail.com (Piotr Wasik) Date: Sat, 2 Nov 2013 21:03:06 +0000 Subject: [closer-devel] c2mop:standard-class not used in lispworks Message-ID: Hi, I have tried the following in LispWorks: CL-USER 1 > (c2cl:defclass foo () ((s1))) # CL-USER 2 > (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) Error: The slot # is missing from # (of class #) The thing is that specialisation defined in https://github.com/mcna/closer-mop/blob/master/closer-lispworks.lisp uses standard-class from c2mop, which is later exported, but nothing forces subsequent code to use it instead of cl:standard-class. Of course (eq (find-class 'cl:standard-class) (find-class 'c2mop:standard-class)) --> NIL When I explicitely use c2mop:standard-class however, the specialisation from closer-mop.lisp is used: (c2cl:defclass foo () ((s1)) (:metaclass c2mop:standard-class)) (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) NIL As expected. How can it be fixed please? Is there any test suite that can check what other functionality is affected? Cheers, Piotr -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotr.wasik at gmail.com Sun Nov 3 13:33:51 2013 From: piotr.wasik at gmail.com (Piotr Wasik) Date: Sun, 3 Nov 2013 13:33:51 +0000 Subject: [closer-devel] c2mop:standard-class not used in lispworks In-Reply-To: <7397ABEA-9975-4601-BE92-2C7883F0DF3F@p-cos.net> References: <7397ABEA-9975-4601-BE92-2C7883F0DF3F@p-cos.net> Message-ID: Hi, Thanks for your explanation. I do agree with your choice - built-in performance optimisation over standardised MOP by default. As of my specific problem, I did not write the code that calls MOP, it is here: https://github.com/erikg/ucw-core/blob/master/src/rerl/standard-component/standard-component.lispSearch for slot-value-using-class and slot-boundp-using-class in this file. It belongs to UCW library. It works fine in SBCL because SBCL uses 'native' MOP, and I tried to run it in LispWorks. I do not deny it could be rewritten to use more common slot-boundp and slot-value calls, but for now, the simpler solution is to use c2mop:standard-class rather than cl:standard-class. UCW uses its own standard-component-class so the price in performance is already paid, as optimisations for standard-class you mentioned are not used. Cheers, Piotr 2013/11/3 Pascal Costanza > Hi, > > Unfortunately, it?s not possible to fix this. > > In Closer to MOP, I have to balance a couple of requirements, and I cannot > fulfill them all. > > In LispWorks, the default protocol for slot accesses is based on symbols, > not on effective slot definition objects. (This is how the CLOS MOP draft > specifications have been defined up until very late in the CLOS MOP > specification process.) > > So by default, you say something like (slot-value-using-class (find-class > ?foo) (make-instance ?foo) ?s1), which is understood by LispWorks?s CLOS > implementation (or better yet, just the plain (slot-value (make-instance > ?foo) ?s1)). > > The goal of Closer to MOP is to change the protocols so they are more in > line with what the actual CLOS MOP specification says. In order to be able > to do this, I have to provide two specializations on slot-value-using-class > and friends. The first is a method that still dispatches on slot names that > then calls slot-value-using-class again with the respective effective slot > definition object. The method looks like this: > > (cl:defmethod slot-value-using-class > ((class standard-class) object (slot symbol)) > (declare (optimize (speed 3) (debug 0) (safety 0) > (compilation-speed 0))) > (let ((slotd (find-slot slot class))) > (if slotd > (slot-value-using-class class object slotd) > (slot-missing class object slot 'slot-value)))) > > Now, I also need to define a method for effective slot definition objects, > which is not provided by default in LispWorks, to make this all work. It > looks like this: > > (cl:defmethod slot-value-using-class > ((class standard-class) object (slotd > standard-effective-slot-definition)) > (declare (optimize (speed 3) (debug 0) (safety 0) > (compilation-speed 0))) > (slot-value-using-class > (load-time-value (class-prototype (find-class 'cl:standard-class))) > object > (slot-definition-name slotd))) > > By calling slot-value-using-class again on the slot name, but this time on > the original cl:standard-class instead of Closer to MOP?s standard-class, I > now get back the original LispWorks slot access. > > I cannot specialize the first method on cl:standard-class. This doesn?t > work, because the CLOS MOP specification explicitly requires that each > user-defined method on the standard protocol generic functions must have at > least one argument specialized on one?s own class. I don?t have a specific > class for the second argument at all, and the third argument must be > specialized on symbol, so what I?m left with is to specialize the first > argument on c2cl:standard-class. The same holds for the second method: > There is no specific specializer available for the second argument, and the > third argument must be standard-effective-slot-definition. (It is > imaginable that the third argument is a subclass of > standard-effective-slot-definition, but that wouldn?t solve your issue > either.) > > If you think about it, it?s clear why the requirement of the CLOS MOP > exists: If I were allowed to define methods on standard protocol functions > that are specialized only on standard metaclasses, this would replace the > default behavior of the CLOS implementation, and thus prevent CLOS from > working at all. > > One way out would be to ?force? every class to be an instance of > c2cl:standard-class instead of cl:standard-class, as you suggest. However, > I decided against that because this would lead to a potentially severe > performance overhead: CLOS implementations make a major effort to implement > the protocols as efficiently as possible if only standard metaclasses are > involved. However, c2cl:standard-class is not a standard metaclass, so the > CLOS implementation would have to resort to much slower generic > implementations of the protocols. I decided it to be more important that > you get best performance for parts of the protocol that are not specialized > in any way for your own metaclasses, and only have an impact on > subprotocols that you effectively change, as much as possible. > > If you subclass c2cl:standard-class, you get the ?fixed? protocols, but if > you don?t, you get the default implementation of LispWorks (same for any > other CL implementation, as far as possible). > > Yes, this means that you sometimes run into issues like the one you > report. But I believe this is a lower price to pay than trying to get > performance back that you may have lost with a more general implementation. > > For your specific problem: Why do you need to call slot-boundp-using-class > manually yourself? This should normally not be required, it?s normally > better to just call slot-boundp? > > Pascal > > On 2 Nov 2013, at 22:03, Piotr Wasik wrote: > > Hi, > > I have tried the following in LispWorks: > > CL-USER 1 > (c2cl:defclass foo () ((s1))) > # > > CL-USER 2 > (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) > > Error: The slot # is missing from # (of class #) > > > The thing is that specialisation defined in > https://github.com/mcna/closer-mop/blob/master/closer-lispworks.lisp uses > standard-class from c2mop, which is later exported, but nothing forces > subsequent code to use it instead of cl:standard-class. > > Of course (eq (find-class 'cl:standard-class) (find-class > 'c2mop:standard-class)) --> NIL > > When I explicitely use c2mop:standard-class however, the specialisation > from closer-mop.lisp is used: > > (c2cl:defclass foo () ((s1)) (:metaclass c2mop:standard-class)) > (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) > NIL > > > As expected. How can it be fixed please? Is there any test suite that can > check what other functionality is affected? > > Cheers, > Piotr > > > -- > Pascal Costanza > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pc at p-cos.net Sun Nov 3 00:15:55 2013 From: pc at p-cos.net (Pascal Costanza) Date: Sun, 3 Nov 2013 01:15:55 +0100 Subject: [closer-devel] c2mop:standard-class not used in lispworks In-Reply-To: References: Message-ID: <7397ABEA-9975-4601-BE92-2C7883F0DF3F@p-cos.net> Hi, Unfortunately, it?s not possible to fix this. In Closer to MOP, I have to balance a couple of requirements, and I cannot fulfill them all. In LispWorks, the default protocol for slot accesses is based on symbols, not on effective slot definition objects. (This is how the CLOS MOP draft specifications have been defined up until very late in the CLOS MOP specification process.) So by default, you say something like (slot-value-using-class (find-class ?foo) (make-instance ?foo) ?s1), which is understood by LispWorks?s CLOS implementation (or better yet, just the plain (slot-value (make-instance ?foo) ?s1)). The goal of Closer to MOP is to change the protocols so they are more in line with what the actual CLOS MOP specification says. In order to be able to do this, I have to provide two specializations on slot-value-using-class and friends. The first is a method that still dispatches on slot names that then calls slot-value-using-class again with the respective effective slot definition object. The method looks like this: (cl:defmethod slot-value-using-class ((class standard-class) object (slot symbol)) (declare (optimize (speed 3) (debug 0) (safety 0) (compilation-speed 0))) (let ((slotd (find-slot slot class))) (if slotd (slot-value-using-class class object slotd) (slot-missing class object slot 'slot-value)))) Now, I also need to define a method for effective slot definition objects, which is not provided by default in LispWorks, to make this all work. It looks like this: (cl:defmethod slot-value-using-class ((class standard-class) object (slotd standard-effective-slot-definition)) (declare (optimize (speed 3) (debug 0) (safety 0) (compilation-speed 0))) (slot-value-using-class (load-time-value (class-prototype (find-class 'cl:standard-class))) object (slot-definition-name slotd))) By calling slot-value-using-class again on the slot name, but this time on the original cl:standard-class instead of Closer to MOP?s standard-class, I now get back the original LispWorks slot access. I cannot specialize the first method on cl:standard-class. This doesn?t work, because the CLOS MOP specification explicitly requires that each user-defined method on the standard protocol generic functions must have at least one argument specialized on one?s own class. I don?t have a specific class for the second argument at all, and the third argument must be specialized on symbol, so what I?m left with is to specialize the first argument on c2cl:standard-class. The same holds for the second method: There is no specific specializer available for the second argument, and the third argument must be standard-effective-slot-definition. (It is imaginable that the third argument is a subclass of standard-effective-slot-definition, but that wouldn?t solve your issue either.) If you think about it, it?s clear why the requirement of the CLOS MOP exists: If I were allowed to define methods on standard protocol functions that are specialized only on standard metaclasses, this would replace the default behavior of the CLOS implementation, and thus prevent CLOS from working at all. One way out would be to ?force? every class to be an instance of c2cl:standard-class instead of cl:standard-class, as you suggest. However, I decided against that because this would lead to a potentially severe performance overhead: CLOS implementations make a major effort to implement the protocols as efficiently as possible if only standard metaclasses are involved. However, c2cl:standard-class is not a standard metaclass, so the CLOS implementation would have to resort to much slower generic implementations of the protocols. I decided it to be more important that you get best performance for parts of the protocol that are not specialized in any way for your own metaclasses, and only have an impact on subprotocols that you effectively change, as much as possible. If you subclass c2cl:standard-class, you get the ?fixed? protocols, but if you don?t, you get the default implementation of LispWorks (same for any other CL implementation, as far as possible). Yes, this means that you sometimes run into issues like the one you report. But I believe this is a lower price to pay than trying to get performance back that you may have lost with a more general implementation. For your specific problem: Why do you need to call slot-boundp-using-class manually yourself? This should normally not be required, it?s normally better to just call slot-boundp? Pascal On 2 Nov 2013, at 22:03, Piotr Wasik wrote: > Hi, > > I have tried the following in LispWorks: > > CL-USER 1 > (c2cl:defclass foo () ((s1))) > # > > CL-USER 2 > (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) > > Error: The slot # is missing from # (of class #) > > The thing is that specialisation defined in https://github.com/mcna/closer-mop/blob/master/closer-lispworks.lisp uses standard-class from c2mop, which is later exported, but nothing forces subsequent code to use it instead of cl:standard-class. > > Of course (eq (find-class 'cl:standard-class) (find-class 'c2mop:standard-class)) --> NIL > > When I explicitely use c2mop:standard-class however, the specialisation from closer-mop.lisp is used: > > (c2cl:defclass foo () ((s1)) (:metaclass c2mop:standard-class)) > (c2mop:slot-boundp-using-class (find-class 'foo) (make-instance 'foo) (first (harlequin-common-lisp:class-slots (find-class 'foo)))) > NIL > > As expected. How can it be fixed please? Is there any test suite that can check what other functionality is affected? > > Cheers, > Piotr -- Pascal Costanza -------------- next part -------------- An HTML attachment was scrubbed... URL: From pc at p-cos.net Wed Nov 6 13:33:00 2013 From: pc at p-cos.net (Pascal Costanza) Date: Wed, 6 Nov 2013 14:33:00 +0100 Subject: [closer-devel] Closer projects moved to sourceforge Message-ID: Hi, I have moved the hosting of the Closer projects (MOP Feature Tests, Closer to MOP, ContextL, Filtered Functions, AspectL, LW Compat) to sourceforge. I also switched from darcs hosting to git hosting. You can find the software now at http://sourceforge.net/p/closer/_list/git All libraries have received new version numbers based on semantic versioning. The mailing lists will from now on also be hosted at sourceforge. Please unsubscribe from the current mailing lists, and subscribe to the mailing lists at http://sourceforge.net/p/closer/mailman/ instead. The information on the Closer webpage at http://common-lisp.net/project/closer/ has also been updated accordingly. Please let me know if you have any questions or problems. Pascal -- Pascal Costanza The views expressed in this email are my own, and not those of my employer.