From: T V Raman
Subject: Could you explain this function:
Date: 
Message-ID: <1994Jan18.205053.25256@cs.cornell.edu>
Hi,

I had posted a query on these newsgroups regarding the use of
compute-applicable-methods and how to code it efficiently.
In response, one of the articles gave me the following function which
does exactly what I want but a lot more efficiently:

(defun lookup-effective-method (gf args)
  ;; Returns the actual function (effective method) that is run when
  ;; GF is applied to ARGS
  ;; You could use this to avoid dispatch overhead if you like.
  (CLOS::CHECKING/CACHING-DCODE-LOOKUP gf args))


I find the function clos::checking/caching-dcode-lookup documented
nowhere in the lucid manual, or in the dpans draft standard.


Though the above function lookup-effective-method does do what I want
I have no idea how it does it!

Could someone explain what the internal clos function is doing and
comment on how safe it is etc?

Thanks

--Raman 
-- 
   T. V. Raman <·····@cs.cornell.edu>Tel: (607)255-9202  Fax:
255-4428
                       Office: 4116 Upson Hall,
Department of Computer Science, Cornell University Ithaca NY 14853-6201

From: Lawrence G. Mayka
Subject: Re: Could you explain this function:
Date: 
Message-ID: <LGM.94Jan19091401@polaris.flw.att.com>
In article <······················@cs.cornell.edu> ·····@cs.cornell.edu (T V Raman) writes:

   I had posted a query on these newsgroups regarding the use of
   compute-applicable-methods and how to code it efficiently.
   In response, one of the articles gave me the following function which
   does exactly what I want but a lot more efficiently:

   (defun lookup-effective-method (gf args)
     ;; Returns the actual function (effective method) that is run when
     ;; GF is applied to ARGS
     ;; You could use this to avoid dispatch overhead if you like.
     (CLOS::CHECKING/CACHING-DCODE-LOOKUP gf args))

   I find the function clos::checking/caching-dcode-lookup documented
   nowhere in the lucid manual, or in the dpans draft standard.

I'm a bit surprised that the Metaobject Protocol (as documented in the
AMOP book) doesn't offer something like this.  It is very common to
want to determine the applicability of a generic function to a list of
arguments before/without actually trying to apply it.
(:SEND-IF-HANDLES was quite popular in the days of Flavors.)
COMPUTE-APPLICABLE-METHODS--as its name suggests--is probably
recomputing the applicable-method list rather than just checking an
effective-method cache.
--
        Lawrence G. Mayka
        AT&T Bell Laboratories
        ···@iexist.att.com

Standard disclaimer.
From: Ken Anderson
Subject: Re: Could you explain this function:
Date: 
Message-ID: <KANDERSO.94Jan20133004@wheaton.bbn.com>
In article <·················@polaris.flw.att.com> ···@polaris.flw.att.com (Lawrence G. Mayka) writes:

      (defun lookup-effective-method (gf args)
	;; Returns the actual function (effective method) that is run when
	;; GF is applied to ARGS
	;; You could use this to avoid dispatch overhead if you like.
	(CLOS::CHECKING/CACHING-DCODE-LOOKUP gf args))

      I find the function clos::checking/caching-dcode-lookup documented
      nowhere in the lucid manual, or in the dpans draft standard.

   I'm a bit surprised that the Metaobject Protocol (as documented in the
   AMOP book) doesn't offer something like this.  It is very common to
   want to determine the applicability of a generic function to a list of
   arguments before/without actually trying to apply it.
   (:SEND-IF-HANDLES was quite popular in the days of Flavors.)

SEND-IF-HANDLES is probably considered bad style these days.  It is better
to write a default method that simply returns NIL.

You can do things like WHICH-OPERATIONS, or OPERATION-HANDLED-P as in
Flavors, though, of course, operations are less tightly coupled to classes
in CLOS:

(defmethod which-methods ((object standard-object))
  (which-methods (class-of object)))

(defmethod which-methods ((class standard-class))
  (let ((methods ())
	(class-t (find-class 't)))
    (dolist (class (clos:class-precedence-list class))
      (unless (eq class class-t)
	(dolist (method (clos:class-direct-methods class))
	  (pushnew method methods :test #'eq))))
    methods))

(defmethod which-generic-functions ((object standard-object))
  (which-generic-functions (class-of object)))

(defmethod which-generic-functions ((class standard-class))
  (let ((gfs ())
	(class-t (find-class 't)))
    (dolist (class (clos:class-precedence-list class))
      (unless (eq class class-t)
	(dolist (method (clos:class-direct-methods class))
	  (pushnew (clos:method-generic-function method) gfs :test #'eq))))
    gfs))

(defmethod operation-handled-p ((generic-function standard-generic-function)
				&rest args)
  (not (null (clos::compute-applicable-methods generic-function args))))

   COMPUTE-APPLICABLE-METHODS--as its name suggests--is probably
   recomputing the applicable-method list rather than just checking an
   effective-method cache.

It is possible that C-A-M could be caching too.  The only thing that CLOS
says is the the effective method gets executed, not that it exists, take
reader methods for example.  Of course, if you know darn well that your
implementation is caching effective methods, it would be nice to use the
implemntation's code rather than writing your own cache.

k
--
Ken Anderson 
Internet: ·········@bbn.com
BBN STC              Work Phone: 617-873-3160
10 Moulton St.       Home Phone: 617-643-0157
Mail Stop 6/4c              FAX: 617-873-3776
Cambridge MA 02138
USA
From: Ken Anderson
Subject: Re: Could you explain this function:
Date: 
Message-ID: <KANDERSO.94Jan19172937@wheaton.bbn.com>
In article <······················@cs.cornell.edu> ·····@cs.cornell.edu (T V Raman) writes:

   Newsgroups: comp.lang.lisp,comp.lang.clos
   Path: news.bbn.com!uhog.mit.edu!europa.eng.gtefsd.com!howland.reston.ans.net!math.ohio-state.edu!jussieu.fr!univ-lyon1.fr!ghost.dsi.unimi.it!batcomputer!cornell!raman
   From: ·····@cs.cornell.edu (T V Raman)
   Keywords: clos internal function: undocumented?
   Organization: Cornell Univ. CS Dept, Ithaca NY 14853
   Date: Tue, 18 Jan 1994 20:50:53 GMT
   Lines: 34
   Xref: news.bbn.com comp.lang.lisp:11766 comp.lang.clos:2274

   I had posted a query on these newsgroups regarding the use of
   compute-applicable-methods and how to code it efficiently.
   In response, one of the articles gave me the following function which
   does exactly what I want but a lot more efficiently:

   (defun lookup-effective-method (gf args)
     ;; Returns the actual function (effective method) that is run when
     ;; GF is applied to ARGS
     ;; You could use this to avoid dispatch overhead if you like.
     (CLOS::CHECKING/CACHING-DCODE-LOOKUP gf args))

   I find the function clos::checking/caching-dcode-lookup documented
   nowhere in the lucid manual, or in the dpans draft standard.

   Though the above function lookup-effective-method does do what I want
   I have no idea how it does it!

   Could someone explain what the internal clos function is doing and
   comment on how safe it is etc?

This is a Lucid internal function.  It is not even in the next version of
Lucid (4.1.1).  Effective methods are cached, so they don't need to be
computed all the time, as you were doing.

You are below the MOP at this point, since effective methods need not
exist, and if they did, you might not be able to execute them outside of
the context of a generic function.

BTW, what are you really trying to do?  Why do you need the effective method?

k
--
Ken Anderson 
Internet: ·········@bbn.com
BBN STC              Work Phone: 617-873-3160
10 Moulton St.       Home Phone: 617-643-0157
Mail Stop 6/4c              FAX: 617-873-3776
Cambridge MA 02138
USA
From: Gregor Kiczales
Subject: Re: Could you explain this function:
Date: 
Message-ID: <GREGOR.94Jan21091412@calvin.parc.xerox.com>
In article <······················@cs.cornell.edu> ·····@cs.cornell.edu (T V Raman) writes:

   I had posted a query on these newsgroups regarding the use of
   compute-applicable-methods and how to code it efficiently.
   In response, one of the articles gave me the following function
   which does exactly what I want but a lot more efficiently:

Hmmm, you've found a clear deficiency in the way PCL, and probably all
of its derivatives, implement the MOP.  I've never seen a case where
someone wanted COMPUTE-APPLICABLE-METHODS to be fast.

This is certainly fixable within the existing MOP spec, but it may
take real work for some vendors to do it.  The problem is that the
high-performance code (ie CLOS::CHECKING/CACHING-DCODE-LOOKUP) *calls*
the slow code (ie COMPUTE-APPLICABLE-METHODS) in cases where it
doesn't already have an answer.  So remodularizing so that CO-APP-ME
can be fast, and also having specialized classes of generic functions
be fast *might* me tricky.  Moreover, there are some bootstrapping
issues here that could complicate things.

For the time being, I'd suggest that you want to be very careful
calling functions like: CLOS::CHECKING/CACHING-DCODE-LOOKUP.  The
danger is that in implementations where these are caches, it may give
you the right answer some of the time, and not other times.  I don't
know what it does in that version of Lucid.

Gregor