[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Method-lambda and apply-method-lambda



I don't think that method-lambda, as describe in 88-003 is good enough.  It
captures the contract between a class of generic functions and a class of methods,
so it should be metaclass driven.  You can imagine several contracts on a single
implementation. 

I propose the following:

Make-method-function is a generic function.

make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT
                                                                                
Generic-function is the generic-function object.  Note that it can be gotten at
compile-file time and is not expected to change incompatibly between
compile-file time and load time.

QUALIFIERS, SPECIALIZERS, LAMBDA-FORM are the "natural" arguments

MACROEXPAND-ENVIRONMENT is necessary in order to capture the lexical context.
It default to the null macroexpand environment.

The generic function make-method-function returns a function suitable for the
function slot of a method. Its representation is implementation dependent.

The example given in 88-003 would be changed to:

(defun trace-gf (gf)
  (let ((nargs (generic-function-required-arguments gf))
        (lambda-list (generic-function-lambda-list gf))
        (specializers (make-list nargs :initial-element (symbol-class 't)))
        (qualifiers '(:around))
        (function (compile () (make-method-function gf qualifiers specializers
	                         `(lambda ,lambda-list
                                     (format *trace-output* "~&Hi there.")
                                     (call-next-method))))))
    (add-method gf
                (make-instance 'standard-method
                               :lambda-list lambda-list
                               :specializers specializers
                               :qualifiers qualifiers
                               :function function))))

I am not sure that compile should or would work on the result of
make-method-function. This must be decided.


(defmethod (setf foo) :before ((x c1) y &rest z) (do-foo ...))

would expand into

(let ((gf (ensure-generic-function '(setf foo))))
  (add-named-method  gf  '(:before)
    '((x c1) y &rest z) 
    (make-method-function gf '(:before) '(c1 t)
	           '(lambda (x y &rest z) (do-foo ...))) environment))

---------


apply-method-lambda must be changed for the same reasons.

I propose the following:

apply-method METHOD NEXT-METHOD-LIST &rest ARGUMENTS [ generic function]

apply-method  is discriminated on METHOD.

METHOD is the method that needs to be invoked.
                                                                                
NEXT-METHOD-LIST is the list of all the methods that can be invoked by calling
call-next-method.

ARGUMENTS are the "external" arguments to the method.  The last one should be a
list of remaining arguments.

Implementations are free to optimize this to internal function calling primitives.


Patrick.