I would like to add some keywords to slot definition, ie. define a
class like this:
(defclass my-cl ()
((info :initarg :info
:accessor info
:attributes '(last-modified))))
I couldn't deduce from AMOP how to persuade the compiler to accept the
additional option (:attributes). I have found an example in posting by
Kenny Tilton, which was supposed to work in ACL 5.0:
http://groups.google.pl/groups?q=compute-effective-slot-definition-initargs&hl=pl&lr=&ie=UTF-8&oe=UTF-8&selm=3CF3AAF2.D28F9B5%40nyc.rr.com&rnum=4
But I've failed to get it working under ACL 6.2. I suppose there is no
portable way of doing this.
Thanks, /S
Slawek Zak wrote:
> I would like to add some keywords to slot definition, ie. define a
> class like this:
>
> (defclass my-cl ()
> ((info :initarg :info
> :accessor info
> :attributes '(last-modified))))
>
> I couldn't deduce from AMOP how to persuade the compiler to accept the
> additional option (:attributes). I have found an example in posting by
> Kenny Tilton, which was supposed to work in ACL 5.0:
>
> http://groups.google.pl/groups?q=compute-effective-slot-definition-initargs&hl=pl&lr=&ie=UTF-8&oe=UTF-8&selm=3CF3AAF2.D28F9B5%40nyc.rr.com&rnum=4
>
> But I've failed to get it working under ACL 6.2. I suppose there is no
> portable way of doing this.
How does it fail? Can you post (or send me) a one file sample of what
you tried? I would be very surprised if we could not get this to work
under AllegroCL 6.2. It is a delicate framework of information one has
to set up, so you might have just made a small mistake.
kenny
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton wrote:
>
>
> Slawek Zak wrote:
>
>> I would like to add some keywords to slot definition, ie. define a
>> class like this:
>>
>> (defclass my-cl ()
>> ((info :initarg :info
>> :accessor info
>> :attributes '(last-modified))))
>>
>> I couldn't deduce from AMOP how to persuade the compiler to accept the
>> additional option (:attributes). I have found an example in posting by
>> Kenny Tilton, which was supposed to work in ACL 5.0:
>>
>> http://groups.google.pl/groups?q=compute-effective-slot-definition-initargs&hl=pl&lr=&ie=UTF-8&oe=UTF-8&selm=3CF3AAF2.D28F9B5%40nyc.rr.com&rnum=4
>>
>>
>> But I've failed to get it working under ACL 6.2. I suppose there is no
>> portable way of doing this.
I forgot to mention: no, work leveraging any implementations MOP is not
portable. Different implementations have different MOPs, and some have
none. This is why I cannot readily confirm my code still works under
AllegroCL 6.2 -- I stopped using the MOP for Cells to get greater
portability.
But I doubt the 5.0->6.2 switch is why your code is not working. The
excerpt in my message was advertised as "for discussion only". It looked
complete when I looked at it just now, but I may have left out some
crucial deets.
If you just want to use ACL6.2, I am sure we can make it work. If you
need cross-implementation portability, my current Cells implementation
handles custom slot initargs without the MOP (via macrology).
kenny
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
> Slawek Zak wrote:
> > I would like to add some keywords to slot definition, ie. define a
> > class like this:
> >
> > (defclass my-cl ()
> > ((info :initarg :info
> > :accessor info
> > :attributes '(last-modified))))
> >
> > I couldn't deduce from AMOP how to persuade the compiler to accept the
> > additional option (:attributes). I have found an example in posting by
> > Kenny Tilton, which was supposed to work in ACL 5.0:
> >
> > http://groups.google.pl/groups?q=compute-effective-slot-definition-initargs&hl=pl&lr=&ie=UTF-8&oe=UTF-8&selm=3CF3AAF2.D28F9B5%40nyc.rr.com&rnum=4
> >
> > But I've failed to get it working under ACL 6.2. I suppose there is no
> > portable way of doing this.
>
> How does it fail? Can you post (or send me) a one file sample of what
> you tried? I would be very surprised if we could not get this to work
> under AllegroCL 6.2. It is a delicate framework of information one has
> to set up, so you might have just made a small mistake.
I have simply cleaned up the example from your posting a little bit,
and it doesn't compile. I'm new to MOP, so it's hard to tell for me
what went wrong :/, but it seems that neither
direct-slot-definition-class nor compute-effective-slot-definition are
called, as I don't have your macros defined and they are not missing
in compilation :)
Here goes the error :
Error: :semaphor are invalid initargs to make-instance of class #<standard-class aclmop:standard-direct-slot-definition>. The valid initargs are
:class excl::fixed-index :writers :readers :allocation :initargs :initfunction :initform :documentation :name :type.
[condition type: program-error]
Restart actions (select using :continue):
0: Ignore
1: Abort entirely from this process.
[Current process: evaluation request 14]
[1c] cl-user(1):
Your :semaphor example, slightly modified.
;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
;; Declarations
(defclass ModelClass (standard-class)
())
;;-------------- Linking / Producing Slot Defs -----------------
;; The keyword parameter semaphor lets you code up a slot option
;; "... :semaphor t ..." In this case I use a custom /direct/ slot
;; definition for what I call semaphoric slots.
;; You might not need to do that.
(defmethod direct-slot-definition-class ((mClass ModelClass) &rest iargs &key semaphor)
;;(trc "DSD-class ModelClass> iargs" iargs)
(if semaphor
(find-class 'SemaphorDSD)
(call-next-method)))
;; Later on we take all direct slot definitions ("dsds" below; they
;; come from any superclass explicitly listing this slot name) and
;; cook up an effective slot definition. Note that I use the :semaphor
;; option value specified to decide which of several semaphor ESD
;; subclasses to instantiate:
(defmethod compute-effective-slot-definition :around ((mClass ModelClass) slot dsds)
(declare (ignorable slot))
(bIf (smd (find-if (lambda (dsd)
(typep dsd 'SemaphorDSD))
dsds)) ;; bind to 'smd closest
(apply #'make-instance
(case (semaphor smd)
(:ephemeral 'SMEphemeralESD)
(:stream 'SMStreamESD)
(:delta 'SMDeltaESD)
(otherwise 'SemaphorESD))
:smWhen (smWhen smd) ;another custom slot option which
(clos::compute-effective-slot-definition-initargs mClass dsds))
(call-next-method))) ;; punt to standard ESD
;;------------ Slot Def Classes ---------------------------
(defclass SemaphorDSD (standard-direct-slot-definition)
((semaphor :initarg :semaphor ;; type, inter alia [:normal t] :ephemeral :delta :drifter :stream
:initform nil
:accessor semaphor)
(smWhen :initarg :smWhen
:initform nil
:reader smWhen)))
;;--------------- ESDs ------------------------------------
(defclass SemaphorESD (standard-effective-slot-definition)
((smWhen :initarg :smWhen
:initform nil
:reader smWhen)
(smindex :initform nil ;cache offset of self in (class-slots <theClass>)
:accessor smIndex)))
(defclass Model ()
((mdValue :initform nil
:accessor mdvalue
:initarg :mdValue
:semaphor t))
(:metaclass ModelClass))
[also posted to c.l.l]
Slawek Zak wrote:
> I have simply cleaned up the example from your posting a little bit,
> and it doesn't compile. I'm new to MOP, so it's hard to tell for me
> what went wrong :/, but it seems that neither
> direct-slot-definition-class nor compute-effective-slot-definition are
> called, as I don't have your macros defined and they are not missing
> in compilation :)
OK, you definitely missed the bit at the end where I said it was posted
just to find out how much the other bloke recognized. :)
The problem is that that code (in my project) gets compiled in a package
which uses AllegroCL packages EXCL and MOP. Below is a version which
works when compiled in CL-USER (unaltered under ACL62), explicitly
referencing EXCL and MOP as necessary.
Without that, you are creating methods of a new generic function of the
same string name but of a different symbol. This would show up if you
did (apropos 'direct-slot-definition-class. You would see two listings:
direct-slot-definition-class
mop::direct-slot-definition-class
If CL required explicit DEFGENERICs your method could not compile and
you might have sorted this out, but then programming CLOS would be
pretty aggravating.
When you compile the defmodel form you should see print output from the
DSD call. When you finalize you will hit the ESD call.
kenny
(in-package :cl-user)
;; Declarations
(defclass ModelClass (standard-class)
())
;;-------------- Linking / Producing Slot Defs -----------------
;; The keyword parameter semaphor lets you code up a slot option
;; "... :semaphor t ..." In this case I use a custom /direct/ slot
;; definition for what I call semaphoric slots.
;; You might not need to do that.
(defmethod mop::direct-slot-definition-class ((mClass ModelClass) &rest
iargs &key semaphor)
(print `("DSD-class ModelClass> iargs" ,@iargs))
(if semaphor
(find-class 'SemaphorDSD)
(call-next-method)))
;;------------ Slot Def Classes ---------------------------
(defclass SemaphorDSD (mop::standard-direct-slot-definition)
((semaphor :initarg :semaphor
:initform nil
:accessor semaphor)
(smWhen :initarg :smWhen
:initform nil
:reader smWhen)))
;;--------------- ESDs ------------------------------------
(defclass SemaphorESD (mop::standard-effective-slot-definition)
((smWhen :initarg :smWhen
:initform nil
:reader smWhen)
(smindex :initform nil
:accessor smIndex)))
;; Later on we take all direct slot definitions ("dsds" below; they
;; come from any superclass explicitly listing this slot name) and
;; cook up an effective slot definition. Note that I use the :semaphor
;; option value specified to decide which of several semaphor ESD
;; subclasses to instantiate:
(defmethod mop::compute-effective-slot-definition :around ((mClass
ModelClass) slot dsds)
(declare (ignorable slot))
(print `(esd sees ,slot ,@dsds))
(let ((smd (find-if (lambda (dsd)
(typep dsd 'SemaphorDSD))
dsds)))
(if smd ;; bind to 'smd closest
(apply #'make-instance
(case (semaphor smd)
(:ephemeral 'SMEphemeralESD)
(:stream 'SMStreamESD)
(:delta 'SMDeltaESD)
(otherwise 'SemaphorESD))
:smWhen (smWhen smd)
(excl::compute-effective-slot-definition-initargs mClass dsds))
(call-next-method)))) ;; punt to standard ESD
#+test-dsd
(defclass Model ()
((mdValue :initform nil
:accessor mdvalue
:initarg :mdValue
:semaphor t
))
(:metaclass ModelClass))
#+test-esd
(mop::finalize-inheritance (find-class 'model))
>
> Here goes the error :
>
> Error: :semaphor are invalid initargs to make-instance of class #<standard-class aclmop:standard-direct-slot-definition>. The valid initargs are
> :class excl::fixed-index :writers :readers :allocation :initargs :initfunction :initform :documentation :name :type.
> [condition type: program-error]
>
> Restart actions (select using :continue):
> 0: Ignore
> 1: Abort entirely from this process.
> [Current process: evaluation request 14]
> [1c] cl-user(1):
>
>
> Your :semaphor example, slightly modified.
>
> ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
>
> ;; Declarations
> (defclass ModelClass (standard-class)
> ())
>
> ;;-------------- Linking / Producing Slot Defs -----------------
> ;; The keyword parameter semaphor lets you code up a slot option
> ;; "... :semaphor t ..." In this case I use a custom /direct/ slot
> ;; definition for what I call semaphoric slots.
> ;; You might not need to do that.
> (defmethod direct-slot-definition-class ((mClass ModelClass) &rest iargs &key semaphor)
> ;;(trc "DSD-class ModelClass> iargs" iargs)
> (if semaphor
> (find-class 'SemaphorDSD)
> (call-next-method)))
>
> ;; Later on we take all direct slot definitions ("dsds" below; they
> ;; come from any superclass explicitly listing this slot name) and
> ;; cook up an effective slot definition. Note that I use the :semaphor
> ;; option value specified to decide which of several semaphor ESD
> ;; subclasses to instantiate:
>
> (defmethod compute-effective-slot-definition :around ((mClass ModelClass) slot dsds)
> (declare (ignorable slot))
> (bIf (smd (find-if (lambda (dsd)
> (typep dsd 'SemaphorDSD))
> dsds)) ;; bind to 'smd closest
> (apply #'make-instance
> (case (semaphor smd)
> (:ephemeral 'SMEphemeralESD)
> (:stream 'SMStreamESD)
> (:delta 'SMDeltaESD)
> (otherwise 'SemaphorESD))
> :smWhen (smWhen smd) ;another custom slot option which
> (clos::compute-effective-slot-definition-initargs mClass dsds))
> (call-next-method))) ;; punt to standard ESD
>
> ;;------------ Slot Def Classes ---------------------------
> (defclass SemaphorDSD (standard-direct-slot-definition)
> ((semaphor :initarg :semaphor ;; type, inter alia [:normal t] :ephemeral :delta :drifter :stream
> :initform nil
> :accessor semaphor)
> (smWhen :initarg :smWhen
> :initform nil
> :reader smWhen)))
>
> ;;--------------- ESDs ------------------------------------
> (defclass SemaphorESD (standard-effective-slot-definition)
> ((smWhen :initarg :smWhen
> :initform nil
> :reader smWhen)
> (smindex :initform nil ;cache offset of self in (class-slots <theClass>)
> :accessor smIndex)))
>
> (defclass Model ()
> ((mdValue :initform nil
> :accessor mdvalue
> :initarg :mdValue
> :semaphor t))
> (:metaclass ModelClass))
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
> [also posted to c.l.l]
>
> Slawek Zak wrote:
>
> > I have simply cleaned up the example from your posting a little bit,
> > and it doesn't compile. I'm new to MOP, so it's hard to tell for me
> > what went wrong :/, but it seems that neither
> > direct-slot-definition-class nor compute-effective-slot-definition are
> > called, as I don't have your macros defined and they are not missing
> > in compilation :)
>
> OK, you definitely missed the bit at the end where I said it was posted
> just to find out how much the other bloke recognized. :)
>
> The problem is that that code (in my project) gets compiled in a package
> which uses AllegroCL packages EXCL and MOP. Below is a version which
> works when compiled in CL-USER (unaltered under ACL62), explicitly
> referencing EXCL and MOP as necessary.
I'm new to MOP - told ya :)
> Without that, you are creating methods of a new generic function of the
> same string name but of a different symbol. This would show up if you
> did (apropos 'direct-slot-definition-class. You would see two listings:
>
> direct-slot-definition-class
> mop::direct-slot-definition-class
>
> If CL required explicit DEFGENERICs your method could not compile and
> you might have sorted this out, but then programming CLOS would be
> pretty aggravating.
>
> When you compile the defmodel form you should see print output from the
> DSD call. When you finalize you will hit the ESD call.
And that's the cookie I wanted. Indeed works in ACL 6.2. Thanks a
lot Kenny :)
/S
Slawek Zak wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>[also posted to c.l.l]
>>
>>Slawek Zak wrote:
>>
>>
>>>I have simply cleaned up the example from your posting a little bit,
>>>and it doesn't compile. I'm new to MOP, so it's hard to tell for me
>>>what went wrong :/, but it seems that neither
>>>direct-slot-definition-class nor compute-effective-slot-definition are
>>>called, as I don't have your macros defined and they are not missing
>>>in compilation :)
>>
>>OK, you definitely missed the bit at the end where I said it was posted
>>just to find out how much the other bloke recognized. :)
>>
>>The problem is that that code (in my project) gets compiled in a package
>>which uses AllegroCL packages EXCL and MOP. Below is a version which
>>works when compiled in CL-USER (unaltered under ACL62), explicitly
>>referencing EXCL and MOP as necessary.
>
>
> I'm new to MOP - told ya :)
OK, but are you aware now that the reason my code did not work for you
had nothing to do with the MOP? As per:
>
>
>>Without that, you are creating methods of a new generic function of the
>>same string name but of a different symbol. This would show up if you
>>did (apropos 'direct-slot-definition-class. You would see two listings:
>>
>> direct-slot-definition-class
>> mop::direct-slot-definition-class
I ask only to make sure you have an awareness of the possibility of this
"gotcha" /whenever/ you are debugging CL. I did not spot the package
issue right away, I ran the code and saw it did not work. I put a print
statement in the DSD generator and saw it did not run. My first guess
was pretty dumb, viz. that ACL might have changed the API, so I did
apropos on some small part of direct-slot-definition-class looking for
a possible new function name. When I saw the two symbols come up (one
with, one without the mop:: package prefix), I knew that was wrong: if
my defmethod d-s-d-c had been read by the reader in a package which
could see the mop symbol, it would not have generated a second one for
dsdc. Ergo I had to either use the mop:: prefix everywhere or (use
:mop). I went with the former.
This comes up often enough in CL programming that it is worth spending
some time to absorb. And again, it is not a MOP issue.
kenny
Kenny Tilton <·······@nyc.rr.com> writes:
> Slawek Zak wrote:
> I ask only to make sure you have an awareness of the possibility of this
> "gotcha" /whenever/ you are debugging CL. I did not spot the package
> issue right away, I ran the code and saw it did not work. I put a print
> statement in the DSD generator and saw it did not run. My first guess
> was pretty dumb, viz. that ACL might have changed the API, so I did
> apropos on some small part of direct-slot-definition-class looking for
> a possible new function name. When I saw the two symbols come up (one
> with, one without the mop:: package prefix), I knew that was wrong: if
> my defmethod d-s-d-c had been read by the reader in a package which
> could see the mop symbol, it would not have generated a second one for
> dsdc. Ergo I had to either use the mop:: prefix everywhere or (use
> :mop). I went with the former.
>
> This comes up often enough in CL programming that it is worth spending
> some time to absorb. And again, it is not a MOP issue.
Yep. Got that. I wasn't aware of the fact that you have to put your
subclass in the aclmop package to make it `active' for slot
definition. I took for granted that your code works in my package when
the compiler groked all but the last statement (the one actually using
the extended slot definition).
Next stop for me is tracing all exported functions in aclmop to find
out how it really works :) It's AMOP compliant and all, but for me
after second reading of the first four chapters of `The Book' it's
still all fuzzy.
Thanks again :)
/S
PS: It took me 30 minutes Googling to find you response to a question
similar to mine! I hope to beat the time down to around 5 minutes but
I must know what to ask about first!
Slawek Zak wrote:
> Yep. Got that. I wasn't aware of the fact that you have to put your
> subclass in the aclmop package to make it `active' for slot
> definition.
No, that is not what I did. The class is defined in CL-USER. When
defining the specializations of things like
direct-slot-definition-class, I used the MOP:: prefix so the method
would get added to the same GF, instead of a new GF of the same string
name. But when Cells worked via the MOP, the cells defpackage form said:
(:use #:aclmop...
I could also have specified each necessary symbol:
(:import-from #:aclmop #:direct-slot-definition-class...
> Next stop for me is tracing all exported functions in aclmop to find
> out how it really works :) It's AMOP compliant...
It's pretty close, but I do recall at least one difference early on that
slowed me up for a couple of hours.
and all, but for me
> after second reading of the first four chapters of `The Book' it's
> still all fuzzy.
Wait till you see OpenGL. I have no idea what they are talking about.
:)
kenny
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
Kenny Tilton <·······@nyc.rr.com> writes:
> Slawek Zak wrote:
>
> > Yep. Got that. I wasn't aware of the fact that you have to put your
> > subclass in the aclmop package to make it `active' for slot
> > definition.
>
> No, that is not what I did. The class is defined in CL-USER. When
> defining the specializations of things like
> direct-slot-definition-class, I used the MOP:: prefix so the method
> would get added to the same GF, instead of a new GF of the same string
> name. But when Cells worked via the MOP, the cells defpackage form said:
Oh. That's why you referred to explicit defgeneric! This would make me
notice, that I don't just add method to GF but make a new one in my
own package. Ok. :) In general case it would be PITA to not have the
automatic GF declarations - yes :)
> (:use #:aclmop...
That's what I use now. I wonder why people use the #:symbol gizmo. Is
there any other reason besides avoiding to clutter the already
cluttered keyword package and save some time spent on interning the symbol?
> > after second reading of the first four chapters of `The Book' it's
> > still all fuzzy.
>
> Wait till you see OpenGL. I have no idea what they are talking about.
Um. I suppose it's great comparing to pure Xlib :) The Cello
screenshots look promising, BTW
/S
Slawek Zak wrote:
> Oh. That's why you referred to explicit defgeneric! This would make me
> notice, that I don't just add method to GF but make a new one in my
> own package. Ok. :) In general case it would be PITA to not have the
> automatic GF declarations - yes :)
Now you got it. :)
>
>
>> (:use #:aclmop...
>
>
> That's what I use now. I wonder why people use the #:symbol gizmo. Is
> there any other reason besides avoiding to clutter the already
> cluttered keyword package and save some time spent on interning the symbol?
I forget. :) I think this has to do with not ending up with symbols in
the package in which the defpackage form gets evaluated. The other trick
is to do (:use "ACLMOP"....
>
>
>>>after second reading of the first four chapters of `The Book' it's
>>>still all fuzzy.
>>
>>Wait till you see OpenGL. I have no idea what they are talking about.
>
>
> Um. I suppose it's great comparing to pure Xlib :) The Cello
> screenshots look promising, BTW
Thanks. By the time I got all the demos resurrected last night I was too
tired to upload the new screenshots. (It is a bit of a hassle.) So now I
am resurrecting the graphical object inspector so I can add a screen
shot of that as well. That needs a bit of work, but today sometime.
kenny
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application