🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.clos
Article #86

Re: no-applicable-method

#86
From: Barry Margolin
Date: Thu, 16 Apr 1992 02:47
60 lines
2876 bytes
In article <odvAqcy00iQQRD=Fo6@andrew.cmu.edu> mh5l+@andrew.cmu.edu (Mohammed M. Hakim) writes:
>Suppose I want to write a no-applicable-method that can be used to
>delegate messages to an object's prototype,  I'll have something that
>looks like this:
>
>(defclass foo () ((prototype)))
>
>(defmethod no-applicable-method ((gf standard-generic-function)
>					&rest args)
>	(let ((prototype (prototype (first args))))
>	   (if prototype
>	        (apply gf prototype (cdr args))
>	        (call-next-method))))
>
>
>This seems to work fine.  However, it blows up when it is used with a
>writer method (setf . .), because for (setf . .) the first argument in
>&rest passed to no-applicable-method is the value of the slot not the
>object instance. Is there a better way to do this. Also, how can I do
>this for multiple qualified arguments?

You can't do it this simply.  As you've noticed, not all generic functions
specialize on the first argument.  CLOS doesn't have the general notion of
"self" in methods; many ideas that make sense in Flavors, Smalltalk, or C++
don't apply to CLOS because of this difference.

A non-object-oriented way to do what you want to do is to have a CASE
statement in your NO-APPLICABLE-METHOD method, to determine the argument
that you should delegate to based on the name of the generic function that
failed.  You could modularize this by creating a separate table mapping
generic function names to argument numbers.

But it might be better to use an OO technique.  Define subclasses of
GENERIC-FUNCTION that delegate on specific arguments, and use this as the
metaclass of the generic functions that you want to be delegated.
Something like:

(defclass delegatable-normal-gf (generic-function))

(defmethod no-applicable-method ((gf delegatable-normal-gf) &rest args)
  (let ((prototype (prototype (first args))))
    (if prototype
	(apply gf prototype (cdr args))
	(call-next-method))))

(defclass delegatable-setf-gf (generic-function))

(defmethod no-applicable-method ((gf delegatable-setf-gf) new-value object)
  (let ((prototype (prototype object)))
    (if prototype
	(apply gf prototype new-value)
	(call-next-method))))

However, this won't work if you're trying to do this to generic functions
that you don't define yourself, since you can't override their metaclasses.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

barmar@think.com          {uunet,harvard}!think!barmar
Technical Details
Message-ID: <kupqlnINNkol@early-bird.think.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!barmar
References: <odvAqcy00iQQRD=Fo6@andrew.cmu.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!think.com!barmar
From: barmar@think.com (Barry Margolin)
Newsgroups: comp.lang.clos
Subject: Re: no-applicable-method
Date: 16 Apr 1992 02:47:19 GMT
Organization: Thinking Machines Corporation, Cambridge MA, USA
Lines: 60
Message-ID: <kupqlnINNkol@early-bird.think.com>
References: <odvAqcy00iQQRD=Fo6@andrew.cmu.edu>
NNTP-Posting-Host: gandalf.think.com