Suppose I do this:
(deftype mytype () 'integer)
(defclass foo ((bar :type mytype)))
In a Common Lisp that provides an AMOP compliant MOP, is it reasonable
to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
slot definition of BAR?
-Peter
--
Peter Seibel * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
Peter Seibel wrote:
> Suppose I do this:
>
> (deftype mytype () 'integer)
>
> (defclass foo ((bar :type mytype)))
>
> In a Common Lisp that provides an AMOP compliant MOP, is it reasonable
> to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
> slot definition of BAR?
I have just checked: clisp returns (AND MYTYPE), all others return MYTYPE.
Pascal
--
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
Pascal Costanza <··@p-cos.net> writes:
> Peter Seibel wrote:
>> Suppose I do this:
>> (deftype mytype () 'integer)
>> (defclass foo ((bar :type mytype)))
>> In a Common Lisp that provides an AMOP compliant MOP, is it
>> reasonable
>> to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
>> slot definition of BAR?
>
> I have just checked: clisp returns (AND MYTYPE), all others return MYTYPE.
Hmmm. Pity. I was hoping that I'd be able to count on getting back the
actual type specification I gave so I could use mop reflection to do
things like generate database schemas based on classes i had defined.
-Peter
--
Peter Seibel * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
Peter Seibel wrote:
> Hmmm. Pity. I was hoping that I'd be able to count on getting back the
> actual type specification I gave so I could use mop reflection to do
> things like generate database schemas based on classes i had defined.
See Christophe's reply why this wouldn't be so straightforward in the
general case. Since CLOS defines a specific way how to combine type
declarations for slots, this means that you need a different object
model. And this is pretty straightforward to achieve with your own
metaclass. Here is a sketch.
; we need a new metaclass
(defclass db-class (standard-class)
())
(defmethod validate-superclass
((class db-class)
(superclass standard-class))
t)
; a slot needs a "database type"
(defclass db-slot-definition (standard-slot-definition)
((dbtype :initarg :dbtype
:initform 't
:accessor slot-dbtype
:reader slot-definition-dbtype)))
; a direct slot is the slot as it appears in a defclass
; form. an effective slot is the slot as it is combined
; from all occurences in the class and all superclasses
(defclass db-direct-slot-definition
(standard-direct-slot-definition db-slot-definition)
())
(defclass db-effective-slot-definition
(standard-effective-slot-definition db-slot-definition)
())
(defmethod direct-slot-definition-class
((class db-class) &rest initargs)
(declare (dynamic-extent initargs))
(find-class 'db-direct-slot-definition))
(defmethod effective-slot-definition-class
((class db-class) &rest initargs)
(declare (dynamic-extent initargs))
(find-class 'db-effective-slot-definition))
; the direct-slot-definitions are given in the order
; of the class precedence list. the "database type"
; is the first one that differs from 't. all others must
; be 't. (change this according to your needs.)
(defmethod compute-effective-slot-definition
((class db-class) name direct-slot-definitions)
(declare (ignore name))
(loop with effective-slot = (call-next-method)
for rest-slots on direct-slot-definitions
unless (eq (slot-dbtype (first rest-slots)) 't) do
(setf (slot-dbtype effective-slot)
(slot-dbtype (first rest-slots)))
(loop-finish)
finally
(assert (loop for slot in (rest rest-slots)
always (eq (slot-dbtype slot) 't))
(return effective-slot)))
Now you can say:
(defclass foo ()
((bar :dbtype integer))
(:metaclass db-class))
Note that this code is not tested.
Pascal
--
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
Peter Seibel <·····@gigamonkeys.com> writes:
> Pascal Costanza <··@p-cos.net> writes:
>> Peter Seibel wrote:
>>> Suppose I do this:
>>> (deftype mytype () 'integer)
>>> (defclass foo ((bar :type mytype)))
>>> In a Common Lisp that provides an AMOP compliant MOP, is it
>>> reasonable
>>> to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
>>> slot definition of BAR?
>> I have just checked: clisp returns (AND MYTYPE), all others return MYTYPE.
> Hmmm. Pity. I was hoping that I'd be able to count on getting back the
> actual type specification I gave so I could use mop reflection to do
> things like generate database schemas based on classes i had defined.
Couldn't you use something like
(flet ((certainly-subtype-p (t1 t2)
(multiple-value-bind (subtypep validp) (subtypep t1 t2)
(and subtypep validp))))
(and (certainly-subtype-p type1 type2)
(certainly-subtype-p type2 type1)))
to determine that MYTYPE is equivalent to (AND MYTYPE)?
Lars Brinkhoff <·········@nocrew.org> writes:
> Peter Seibel <·····@gigamonkeys.com> writes:
>> Hmmm. Pity. I was hoping that I'd be able to count on getting back the
>> actual type specification I gave so I could use mop reflection to do
>> things like generate database schemas based on classes i had defined.
>
> Couldn't you use something like
>
> (flet ((certainly-subtype-p (t1 t2)
> (multiple-value-bind (subtypep validp) (subtypep t1 t2)
> (and subtypep validp))))
> (and (certainly-subtype-p type1 type2)
> (certainly-subtype-p type2 type1)))
>
> to determine that MYTYPE is equivalent to (AND MYTYPE)?
Formally, no implementation is ever required to return T, T for
(subtypep 'mtype '(and mytype)).
Christophe
Christophe Rhodes <·····@cam.ac.uk> writes:
> Formally, no implementation is ever required to return T, T for
> (subtypep 'mtype '(and mytype)).
Right, forgot about CLHS' somewhat weak requirements on subtypep.
I would hope that all contemporary implementations use Henry Baker's
subtypep algorithm (or similar).
Peter Seibel <·····@gigamonkeys.com> writes:
> Suppose I do this:
>
> (deftype mytype () 'integer)
>
> (defclass foo ((bar :type mytype)))
>
> In a Common Lisp that provides an AMOP compliant MOP, is it reasonable
> to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
> slot definition of BAR?
Consider
(defclass foo (bar) ((baz :type fixnum)))
(defclass bar () ((baz :type unsigned-byte)))
The actual declared type of the BAZ slot in instances of FOO is, in
this instance, (AND FIXNUM UNSIGNED-BYTE). While it might possibly be
reasonable for the direct slot definition to have SLOT-DEFINITION-TYPE
eq to FIXNUM (in my case), the effective slot definition should
probably have the intersection type as its SLOT-DEFINITION-TYPE.
Christophe
Peter Seibel wrote:
> Suppose I do this:
>
> (deftype mytype () 'integer)
>
> (defclass foo ((bar :type mytype)))
>
> In a Common Lisp that provides an AMOP compliant MOP, is it reasonable
> to count on SLOT-DEFINITION-TYPE returning the symbol MYTYPE for the
> slot definition of BAR?
I'll point out the obvious by noting that slot-definition-type is a
function of one argument, but you neglect to specify the type of that
argument. The answer (whether defined by the AMOP or not) might very
well be different whether the argument is a direct-slot-definition or an
effective-slot-definition or a complex float.