Lisp HUG Maillist Archive

Problems with FUNCALLABLE-STANDARD-CLASS

Hello,

I'm trying to create a new FUNCALLABLE-STANDARD-CLASS and always get  
an error if I do so. I've reduced it to the following examples.

The following works:

(defclass mixin-without-slots () ())
(defclass my-funcallable-instance (mixin-without-slots  
clos:funcallable-standard-object)
   ()
   (:metaclass clos:funcallable-standard-class))

  (let ((fn (make-instance 'my-funcallable-instance)))
    (set-funcallable-instance-funcation fn (lambda (a b) (+ a b)))
    (funcall fn 2 3))


But the following raises a condition when defining the class.

(defclass mixin-with-slot () (a))
(defclass my-buggy-funcallable-instance (mixin-with-slot  
clos:funcallable-standard-object)
   ()
   (:metaclass clos:funcallable-standard-class))

Error: #<STANDARD-CLASS MIXIN-WITH-SLOT 22DEAEFB> is an invalid  
superclass of #<FUNCALLABLE-STANDARD-CLASS MY-BUGGY-FUNCALLABLE- 
INSTANCE 22E291A7>.

Does anybody know this?
Is there something wrong with this code?

ciao,
Jochen

--
Jochen Schmidt
CRISPYLOGICS
Uhlandstr. 9 , 90408 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:info@crispylogics.com
http://www.crispylogics.com


Re: Problems with FUNCALLABLE-STANDARD-CLASS


On 11 Feb 2009, at 15:08, Jochen Schmidt wrote:

>
> Hello,
>
> I'm trying to create a new FUNCALLABLE-STANDARD-CLASS and always get  
> an error if I do so. I've reduced it to the following examples.
>
> The following works:
>
> (defclass mixin-without-slots () ())
> (defclass my-funcallable-instance (mixin-without-slots  
> clos:funcallable-standard-object)
>  ()
>  (:metaclass clos:funcallable-standard-class))
>
> (let ((fn (make-instance 'my-funcallable-instance)))
>   (set-funcallable-instance-funcation fn (lambda (a b) (+ a b)))
>   (funcall fn 2 3))
>
>
> But the following raises a condition when defining the class.
>
> (defclass mixin-with-slot () (a))
> (defclass my-buggy-funcallable-instance (mixin-with-slot  
> clos:funcallable-standard-object)
>  ()
>  (:metaclass clos:funcallable-standard-class))
>
> Error: #<STANDARD-CLASS MIXIN-WITH-SLOT 22DEAEFB> is an invalid  
> superclass of #<FUNCALLABLE-STANDARD-CLASS MY-BUGGY-FUNCALLABLE- 
> INSTANCE 22E291A7>.
>
> Does anybody know this?
> Is there something wrong with this code?

Your code is correct according to the CLOS MOP specification. However,  
LispWorks has the limitation that standard-class and funcallable- 
standard-class are not compatible with each other in the general case.  
The case that it happens to work if the standard-class doesn't define  
any slots is an exception.

The only way out of this is to duplicate the class hierarchy and make  
one version of the hierarchy be all funcallable-standard-class (and  
keep the original as standard-class). Closer to MOP also doesn't fix  
this - it's just not possible without tweaking internal implementation  
details.

Allegro Common Lisp and CMUCL currently have the same limitation. (In  
general, the generic function protocols are the least stable in most  
CLOS MOP implementations, with different problems everywhere.)  
(LispWorks is actually one of the best ones IMHO. ;)

I hope this helps.

Best,
Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/

Pascal Costanza, mailto:pc@p-cos.net, http://p-cos.net
Vrije Universiteit Brussel
Programming Technology Lab
Artificial Intelligence Lab
Pleinlaan 2, B-1050 Brussel, Belgium





Re: Problems with FUNCALLABLE-STANDARD-CLASS

On Wed, Feb 11, 2009 at 3:30 PM, Pascal Costanza <pc@p-cos.net> wrote:
> On 11 Feb 2009, at 15:08, Jochen Schmidt wrote:
>> But the following raises a condition when defining the class.
>>
>> (defclass mixin-with-slot () (a))
>> (defclass my-buggy-funcallable-instance (mixin-with-slot
>> clos:funcallable-standard-object)
>>  ()
>>  (:metaclass clos:funcallable-standard-class))
>>
>> Error: #<STANDARD-CLASS MIXIN-WITH-SLOT 22DEAEFB> is an invalid superclass
>> of #<FUNCALLABLE-STANDARD-CLASS MY-BUGGY-FUNCALLABLE-INSTANCE 22E291A7>.
>>
>> Does anybody know this?
>> Is there something wrong with this code?
>
> Your code is correct according to the CLOS MOP specification. However,
> LispWorks has the limitation that standard-class and
> funcallable-standard-class are not compatible with each other in the general
> case. The case that it happens to work if the standard-class doesn't define
> any slots is an exception.

Another exception is when you define your own subclass of
funcallable-standard-class, and I think that's a good workaround:

(defclass my-funcallable-meta-class (funcallable-standard-class)
  ())

(defmethod validate-superclass ((class my-funcallable-meta-class) superclass)
  (declare (ignorable class superclass))
  t)

(defclass mixin-with-slot () (a))

(defclass my-buggy-funcallable-instance (mixin-with-slot
clos:funcallable-standard-object)
  ()
  (:metaclass my-funcallable-meta-class))

(let ((fn (make-instance 'my-buggy-funcallable-instance)))
  (clos:set-funcallable-instance-function fn (lambda (a b) (+ a b)))
  (setf (slot-value fn 'a) 42)
  (values (funcall fn 2 3)
          (slot-value fn 'a)))

I'm using a setup like this in CLPython, and it works reliable in
Allegro and Lispworks. The above code also seems to work on SBCL
1.0.20, but I've encountered problems using more complex classes and
metaclasses.

- Willem


Re: Problems with FUNCALLABLE-STANDARD-CLASS

Unable to parse email body. Email id is 8999

Updated at: 2020-12-10 08:41 UTC