Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise.
Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
On Wed, Mar 10, 2010 at 6:43 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise. , Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
I'm afraid there isn't, because all slots (both instance- and class-allocated) are initialized by shared-initialize, as part of the instance initialization protocol[1]. Also note that, as you posted, according to AMOP "The results are undefined if a portable program modifies the binding of any slot of prototype instance", so initializing its slots in any way, even class-allocated ones, is not portable. You should use mop::allocate-instance instead of class-prototype. For the record, in ABCL the two are equivalent, but e.g. in SBCL they aren't (the class prototype is cached).
AFAIK, class-prototype is only useful when you have to call a method specialized on a class C, but which does not use the object of class C in any way except for actually selecting the correct method. With class-prototype, you have an option to call such a method even without an instance of C available.
Alessio
[1] http://www.lispworks.com/documentation/HyperSpec/Body/f_shared.htm
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
Here is how to do it in SBCL. cv? represent class variables. iv? represent instance variables. Both associated to the "class1" class.
(defclass meta-class1 (standard-class) (cv1 cv2 cv3) (:metaclass standard-class))
(defmethod sb-mop:validate-superclass ((class meta-class1) (superclass standard-class)) t)
(defclass class1 (standard-object) (iv1 iv2 iv3) (:metaclass meta-class1))
(setf (slot-value (find-class 'class1) 'cv2) 'hello)
(slot-value (find-class 'class1) 'cv2)
Blake McBride
On Wed, Mar 10, 2010 at 1:11 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 6:43 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise. , Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
I'm afraid there isn't, because all slots (both instance- and class-allocated) are initialized by shared-initialize, as part of the instance initialization protocol[1]. Also note that, as you posted, according to AMOP "The results are undefined if a portable program modifies the binding of any slot of prototype instance", so initializing its slots in any way, even class-allocated ones, is not portable. You should use mop::allocate-instance instead of class-prototype. For the record, in ABCL the two are equivalent, but e.g. in SBCL they aren't (the class prototype is cached).
AFAIK, class-prototype is only useful when you have to call a method specialized on a class C, but which does not use the object of class C in any way except for actually selecting the correct method. With class-prototype, you have an option to call such a method even without an instance of C available.
Alessio
[1] http://www.lispworks.com/documentation/HyperSpec/Body/f_shared.htm
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
BTW, my CLOS utilities make this and other CLOS usage very easy. It also includes a tutorial. See:
http://blake.mcbride.name/software/clos-utils/index.html
Blake McBride
On Wed, Mar 10, 2010 at 1:32 PM, Blake McBride blake@mcbride.name wrote:
Here is how to do it in SBCL. cv? represent class variables. iv? represent instance variables. Both associated to the "class1" class.
(defclass meta-class1 (standard-class) (cv1 cv2 cv3) (:metaclass standard-class))
(defmethod sb-mop:validate-superclass ((class meta-class1) (superclass standard-class)) t)
(defclass class1 (standard-object) (iv1 iv2 iv3) (:metaclass meta-class1))
(setf (slot-value (find-class 'class1) 'cv2) 'hello)
(slot-value (find-class 'class1) 'cv2)
Blake McBride
On Wed, Mar 10, 2010 at 1:11 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 6:43 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise. , Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
I'm afraid there isn't, because all slots (both instance- and class-allocated) are initialized by shared-initialize, as part of the instance initialization protocol[1]. Also note that, as you posted, according to AMOP "The results are undefined if a portable program modifies the binding of any slot of prototype instance", so initializing its slots in any way, even class-allocated ones, is not portable. You should use mop::allocate-instance instead of class-prototype. For the record, in ABCL the two are equivalent, but e.g. in SBCL they aren't (the class prototype is cached).
AFAIK, class-prototype is only useful when you have to call a method specialized on a class C, but which does not use the object of class C in any way except for actually selecting the correct method. With class-prototype, you have an option to call such a method even without an instance of C available.
Alessio
[1] http://www.lispworks.com/documentation/HyperSpec/Body/f_shared.htm
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Wed, Mar 10, 2010 at 8:32 PM, Blake McBride blake@mcbride.name wrote:
Here is how to do it in SBCL. cv? represent class variables. iv? represent instance variables. Both associated to the "class1" class.
(defclass meta-class1 (standard-class) (cv1 cv2 cv3) (:metaclass standard-class))
(defmethod sb-mop:validate-superclass ((class meta-class1) (superclass standard-class)) t)
(defclass class1 (standard-object) (iv1 iv2 iv3) (:metaclass meta-class1))
(setf (slot-value (find-class 'class1) 'cv2) 'hello)
(slot-value (find-class 'class1) 'cv2)
That's a different thing. (slot-value (make-instance 'class1) 'cv2) ==> missing slot, i.e. you're not defining class-allocated slots as specified by the CL standard. I'm not saying your approach is wrong, but probably it's not what the OP asked.
Alessio
Blake McBride
On Wed, Mar 10, 2010 at 1:11 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 6:43 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise. , Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
I'm afraid there isn't, because all slots (both instance- and class-allocated) are initialized by shared-initialize, as part of the instance initialization protocol[1]. Also note that, as you posted, according to AMOP "The results are undefined if a portable program modifies the binding of any slot of prototype instance", so initializing its slots in any way, even class-allocated ones, is not portable. You should use mop::allocate-instance instead of class-prototype. For the record, in ABCL the two are equivalent, but e.g. in SBCL they aren't (the class prototype is cached).
AFAIK, class-prototype is only useful when you have to call a method specialized on a class C, but which does not use the object of class C in any way except for actually selecting the correct method. With class-prototype, you have an option to call such a method even without an instance of C available.
Alessio
[1] http://www.lispworks.com/documentation/HyperSpec/Body/f_shared.htm
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Wed, Mar 10, 2010 at 1:39 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 8:32 PM, Blake McBride blake@mcbride.name wrote:
Here is how to do it in SBCL. cv? represent class variables. iv? represent instance variables. Both associated to the "class1" class.
(defclass meta-class1 (standard-class) (cv1 cv2 cv3) (:metaclass standard-class))
(defmethod sb-mop:validate-superclass ((class meta-class1) (superclass standard-class)) t)
(defclass class1 (standard-object) (iv1 iv2 iv3) (:metaclass meta-class1))
(setf (slot-value (find-class 'class1) 'cv2) 'hello)
(slot-value (find-class 'class1) 'cv2)
That's a different thing. (slot-value (make-instance 'class1) 'cv2) ==> missing slot, i.e. you're not defining class-allocated slots as specified by the CL standard. I'm not saying your approach is wrong, but probably it's not what the OP asked.
(slot-value (make-instance 'class1) 'cv2)
creates an instance. He wanted access to a true class variable, stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
Blake McBride
On Wed, Mar 10, 2010 at 8:50 PM, Blake McBride blake@mcbride.name wrote:
(slot-value (make-instance 'class1) 'cv2)
creates an instance.
Sure, but (slot-value (mop::class-prototype (find-class 'class1)) 'cv2) does not and still fails with a slot-missing error, which was my point.
He wanted access to a true class variable,
no, he wanted to "access class-allocated slot values" in his own words. This, in the context of CL, can only mean slots with :allocation :class.
stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
It's perfectly fine, but cv? are not class-allocated slots, at least not as the CL standard defines them.
Alessio
On Wed, Mar 10, 2010 at 2:12 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 8:50 PM, Blake McBride blake@mcbride.name wrote:
(slot-value (make-instance 'class1) 'cv2)
creates an instance.
Sure, but (slot-value (mop::class-prototype (find-class 'class1)) 'cv2) does not and still fails with a slot-missing error, which was my point.
He wanted access to a true class variable,
no, he wanted to "access class-allocated slot values" in his own words. This, in the context of CL, can only mean slots with :allocation :class.
stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
It's perfectly fine, but cv? are not class-allocated slots, at least not as the CL standard defines them.
Alessio
A class defines what (instance) variables are in instances of itself. A metaclass defines what (class) variables are defined in its instances (the class). Therefore, semantics aside, a metaclass defines what (class) variables are _stored_ in the class itself - not the meta class, and not instances of the class. My example does in fact store the class variables in the class and not in the metaclass since the metaclass defines what variables are in its instances - the class itself.
Blake McBride
Additionally, the :allocation :class thing is just a cheap way of getting a semi-true class variable which is often adequate and doesn't require all the additional machinery of a metaclass definition. It is a convenience for restricted cases and not a true (in every respect) class variable. The code I gave gives a true class variable in all respects - being able to access it without an instance is just one respect.
Blake McBride
On Wed, Mar 10, 2010 at 2:12 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 8:50 PM, Blake McBride blake@mcbride.name wrote:
(slot-value (make-instance 'class1) 'cv2)
creates an instance.
Sure, but (slot-value (mop::class-prototype (find-class 'class1)) 'cv2) does not and still fails with a slot-missing error, which was my point.
He wanted access to a true class variable,
no, he wanted to "access class-allocated slot values" in his own words. This, in the context of CL, can only mean slots with :allocation :class.
stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
It's perfectly fine, but cv? are not class-allocated slots, at least not as the CL standard defines them.
Alessio
Another example is that as you create sub-classes :allocate :class variables don't function like regular instance variables in terms of inheritance. Correctly defined class variables using metaclasses do.
Blake McBride
On Wed, Mar 10, 2010 at 2:12 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 8:50 PM, Blake McBride blake@mcbride.name wrote:
(slot-value (make-instance 'class1) 'cv2)
creates an instance.
Sure, but (slot-value (mop::class-prototype (find-class 'class1)) 'cv2) does not and still fails with a slot-missing error, which was my point.
He wanted access to a true class variable,
no, he wanted to "access class-allocated slot values" in his own words. This, in the context of CL, can only mean slots with :allocation :class.
stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
It's perfectly fine, but cv? are not class-allocated slots, at least not as the CL standard defines them.
Alessio
Hi Blake,
I understand the benefits and I'll consider adopting this approach. The :allocation :class was sufficient in this case and I was curious about what to do absent full metaclass/mop implementation.
Regards, Alan
On Wed, Mar 10, 2010 at 5:36 PM, Blake McBride blake@mcbride.name wrote:
Another example is that as you create sub-classes :allocate :class variables don't function like regular instance variables in terms of inheritance. Correctly defined class variables using metaclasses do.
Blake McBride
On Wed, Mar 10, 2010 at 2:12 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Mar 10, 2010 at 8:50 PM, Blake McBride blake@mcbride.name wrote:
(slot-value (make-instance 'class1) 'cv2)
creates an instance.
Sure, but (slot-value (mop::class-prototype (find-class 'class1)) 'cv2) does not and still fails with a slot-missing error, which was my point.
He wanted access to a true class variable,
no, he wanted to "access class-allocated slot values" in his own words. This, in the context of CL, can only mean slots with :allocation :class.
stored in the class (class1) that was accessible via a class reference. If that's what he wanted, that's exactly what my code does.
My example code does store cv? in class1, not the meta-class.
It's perfectly fine, but cv? are not class-allocated slots, at least not as the CL standard defines them.
Alessio
Yes, there is in CLOS. One would use meta-classes for that. Unfortunately, ABCL does not currently (correctly) support metaclasses. Erik is working on that, partially for the exact use-case you describe.
Blake McBride
On Wed, Mar 10, 2010 at 11:43 AM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
Hi,
Thanks for adding class-prototype. Unfortunately I realize that the specification doesn't guarantee the behavior I was looking for, so I though I would solicit advise.
Basically I want to be able to access class-allocated slot values before I create any real instances. I thought I could grab the class prototype and do slot value on them, but according to the doc below initialize is not called, which I guess is when class-allocated slots are being set up.
Is there a portable way of asking for the values of class slots absent the creation of at least one initialized instance?
-Alan
http://www.franz.com/support/documentation/8.2/doc/mop/dictionary.html#class...
Generic Function class-prototype class
Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of prototype instance.
This generic function signals an error if class has not been finalized.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel@common-lisp.net