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

Anonymous Generic Function Proposal (Draft 2)



Draft 1 is amended to take into account Danny's comment.

There are 3 cases to consider:

	1. Purely anonymous generic functions, corresponding to 
           (function (lambda ...)) in Common Lisp.

	2. A set of named generic functions to be used within a particular
	   body, corresponding to (labels ...) in Common Lisp. An analog
	   to FLET might be appropriate also.

	3. A means of extending a generic function currently defined on a
	   symbol (name) or lexically. This corresponds to nothing in
	   Common Lisp.

Here is a proposal, inspired by Guy Steele, which covers case 1:

(generic (lambda ...)
	 (lambda ...)
	 (lambda ...)
	 ...))

This special form produces a generic function with the lambda-expressions
as the methods. This is about as similar to the FUNCTION syntax as can
be rationally gotten.

To cover case 2 we define an analog to Common Lisp LABELS, but instead of
functions the user defines methods:

(generic-labels ((foo (...)...)
		 (bar (...) ...)
		 (bar (...) ...)
		 (foo (...)...)
 <body>)

This form produces 2 new generic functions, FOO and BAR. 

At this point it is easy to extend FLET similarly:
 
(generic-flet ((foo (...)...)
	       (bar (...) ...)
	       (bar (...) ...)
	       (foo (...)...)
 <body>)

The simplest means of producing an anonymous recursive generic function is:

(generic-labels ((self (...)...(self...)...)
		 (self (...)...(self...)...)
		 ...)
 #'self)

Both GENERIC-LABELS and GENERIC-FLET produce new generic functions. The
fact that a generic function is already bound to a variable of the same
name or to a symbol is irrelevant to the operation of these forms.

Notice that the special form FUNCTION will need to be amended in CLtL to
be able to produce a generic function, but this should be a natural fallout
of making a generic function a subtype of FUNCTION.

Handling case 3 is more difficult, because there is no corresponding
Common Lisp form to do a similar thing for functions.  A danger is to
inadvertently design a form that will also accomplish the dynamic binding
of a function associated with a symbol.

(with-added-methods <generic-function> (<methods>*) . <body>)

This takes a generic function and a list of methods specified as
lambda-expressions, extends the generic function by adding the appropriate
methods, and then executes the forms in <body> as if they were in a PROGN.
When WITH-ADDED-METHODS exits, the added methods are removed. Any flow of
control out of the WITH-ADDED-METHODS causes the methods to be removed.

Notice that this handles both anonymous and named generic functions.
For example:

(generic-flet ((foo (...)...) (foo (...)...))
 (with-added-methods #'print ((lambda (...)...) (lambda (...)...))
  (with-added-methods #'foo ((lambda (...)...)) <body>)))

			-rpg-