19 Jun 20:00
Re: inherited slot types (cmucl)
From: Madhu <enometh <at> meer.net>
Subject: Re: inherited slot types (cmucl)
Newsgroups: gmane.lisp.cmucl.devel
Date: 2008-06-19 18:00:49 GMT
Subject: Re: inherited slot types (cmucl)
Newsgroups: gmane.lisp.cmucl.devel
Date: 2008-06-19 18:00:49 GMT
[cc attempted to cmucl-imp]
* Evan Monroig <87bq1zy3nv.fsf <at> obakechan.net> :
Wrote on Wed, 18 Jun 2008 09:42:28 +0900:
| Hi all,
|
| I am writing some matrix/vector classes and functions [1], and have a
| class hierarchy as follows:
[SNIP]
|
| Error in function PCL::INTERNAL-ERROR:
| Internal error: PCL::SPECIALIZER-APPLICABLE-USING-TYPE-P
| cannot handle the second argument
| (OR (CLASS #<STANDARD-CLASS VECTOR-LIKE {58827525}>)
| (CLASS #<STANDARD-CLASS SIMPLE-MATRIX {587E647D}>)).
|
| But it is ok if I change the definition by explicitly writing the full
| AND type.
I just took a quick initial look at this:
This seems to be SBCL BUG 391 which was fixed in sbcl-0.9.7.1
(2005-11-29 by Christophe Rhodes)
,----
- Typed slots with moderately difficult types, combined with
- subclassing, cause the computation of effective-slot-definitions to
- go awry.
- (defclass foo () ((x :type fixnum)))
- (defclass bar (foo) ((x :type (integer 1 5))))
- gives an error from SB-PCL::SPECIALIZER-APPLICABLE-USING-TYPE-P.
- This is probably because of an inappropriate use of *SUBTYPEP in
- COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS.
`----
The "cannot handle second argument" is thrown by PCL::*SUBTYPEP, which
only handles a few types.
The way SBCL fixes this bug is by simply deleting the branch involving
PCL::*SUBTYPEP which causes the problem. PCL::SUBTYPEP does not deal
with (OR) types or other integer types. The comment in the patch admits
that this solution is neither efficient not elegant, but just it does
get rid of the error. Here is how the [slightly tab-doctored for CMUCL]
patch ported over from SBCL looks like
--- a/pcl/std-class.lisp
+++ b/pcl/std-class.lisp
@@ -1127,9 +1127,14 @@
allocp t))
(setq initargs (append (slot-definition-initargs slotd) initargs))
(let ((slotd-type (slot-definition-type slotd)))
- (setq type (cond ((eq type t) slotd-type)
- ((*subtypep type slotd-type) type)
- (t `(and ,type ,slotd-type)))))))
+ (setq type (cond
+ ((eq type t) slotd-type)
+ ;; This pairwise type intersection is perhaps a
+ ;; little inefficient and inelegant, but it's
+ ;; unlikely to lie on the critical path. Shout
+ ;; if I'm wrong. -- CSR, 2005-11-24
+ (t (kernel:type-specifier
+ (kernel:specifier-type `(and ,type ,slotd-type)))))))))
(list :name name
:initform initform
:initfunction initfunction
I would prefer waiting for a solution that fixes the subtypep branch in the code that causes this problem by teaching it to do types correctly, rather than committing this fix. However I wanted to note this solution so one could apply it in a pinch, if it was a showstopper. -- Madhu
RSS Feed