From: Pascal Costanza
Subject: Help with a design decision in AspectL
Date: 
Message-ID: <cmo8na$s28$1@f1node01.rhrz.uni-bonn.de>
Hi,

I need some help with a design decision in AspectL. In AspectL, special 
generic functions currently need to be defined like this:

(define-special-function some-function (x y z)
   (:definer some-function*))

The :definer option names a generic function that must be used to add 
methods to whereas the "main" name (some-function) is the function that 
must be used for calling the special function. ("Caller" and "definer" 
must be separated in order to make the whole concept work at all.)

Furthermore, methods need to be defined like this:

(defmethod some-function* ((scope t) x y z)
   ...)

or, if you want to define a method in the current dynamic scope:

(defmethod* some-function* ((scope dynamic) x y z)
   ...)

The defmethod* operator must be used in the latter case because most 
CLOS implementations do not provide correct implementations of defmethod 
as specified in AMOP, and I rely on that. (Actually, I rely on the fact 
that make-method-lambda is called, but some CLOS implementations don't 
provide make-method-lambda at all, and those that do don't call it in 
the defmethod macro.)

Furthermore, the first specializer (t or dynamic) is used to make the 
method dispatch work, so that only methods that are valid for the 
current dynamic scope are actually executed.

This design has "evolved" over a few iterations, and by now I think it's 
a mess. Here is what I would actually prefer:

- Special generic functions should be defined like this:

(defgeneric some-function (x y z)
   (:generic-function-class special-function))

- Methods on special functions should be defined like this:

(defmethod some-function (x y z)
   ...)

or

(defmethod some-function (x y z)
   (:scope dynamic)
   ...)

I have experimented with various ways to achieve this, and I am 
confident by now that this would work. However, I would need to 
reimplement the defmethod and maybe even the defgeneric macro.

There are some pros and cons and here:

Pros:

p1) It looks better and more in line with how CLOS is "traditionally" used.

p2) The new defmethod macro would provide a way to pass method options, 
a feature that is currently missing in CLOS. For example, it's not 
currently not possible to name the method class for a method. With the 
new defmethod macro, this would work as follows:

(defmethod do-something (a b c)
   (:method-class non-standard-method)
   ...)

The idea is that not only strings and declarations are processed 
specially, but also all forms that are conses and start with a keyword. 
This is ok AFAICS, because conses that start with a keyword cannot be 
executed in a meaningful way anyway.

p3) The new defmethod and defgeneric macros would conform to the AMOP 
specification which could be worthwhile for other purposes beyond 
AspectL as well. (There is already a MOP utilities package provided as 
part of AspectL that is not strictly related to AspectL and could 
already be used separately.)

Cons:

c1) I need to shadow defmethod and maybe defgeneric. This would have an 
impact on applications and libraries that want to use AspectL.

c2) I don't know (yet?) how to ensure the compile-time semantics of 
those operators as specified in the ANSI spec. The various CLOS 
implementations do this differently and AMOP doesn't specify anything in 
this regard.

c3) I don't know how to interact with the several development 
environments that want to record, for example, source locations of 
method definitions, etc.

c1 can possibly be solved by using different names, but I want to avoid 
that. I don't see any strong reasons to avoid shadowing just because of 
shadowing.

Maybe I can solve c2 in some ways, and I would try to do that, but I 
don't yet see how.

I will probably have no time to solve c3 (but I would accept patches to 
make this work).


I am currently strongly in favor of dropping 
define-special-function/defmethod* and switching to defgeneric/defmethod 
as sketched here, but I would appreciate to hear some other opinions, no 
matter whether strong or not.

So what do you think?


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)

From: Rahul Jain
Subject: Re: Help with a design decision in AspectL
Date: 
Message-ID: <87is89qx8v.fsf@nyct.net>
Pascal Costanza <········@web.de> writes:

> - Special generic functions should be defined like this:
>
> (defgeneric some-function (x y z)
>    (:generic-function-class special-function))
>
> - Methods on special functions should be defined like this:
>
> (defmethod some-function (x y z)
>    ...)
>
> or
>
> (defmethod some-function (x y z)
>    (:scope dynamic)
>    ...)

This syntax is a bit tricky. Initargs can (and often should) be symbols
interned in some package, so it's hard or impossible to guess whether a
form is an option declaration or actual code in a macro. I would do
something like:

(defmethod some-function (x y z)
  (declare (options (scope :dynamic)))
  ...)

Oh wait... that's a whole 'nother can o' worms. :)

So maybe:

(defmethod some-function (x y z)
  :options ((scope :dynamic))
  ...)

Shrug.

> I have experimented with various ways to achieve this, and I am
> confident by now that this would work. However, I would need to
> reimplement the defmethod and maybe even the defgeneric macro.

What would you need to reimplement defgeneric for? Do some
implementations not support specifying a g-f metaclass?

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: Help with a design decision in AspectL
Date: 
Message-ID: <cna9e4$rq6$1@f1node01.rhrz.uni-bonn.de>
Rahul Jain wrote:

> So maybe:
> 
> (defmethod some-function (x y z)
>   :options ((scope :dynamic))
>   ...)
> 
> Shrug.

This looks like a good compromise to me.

>>I have experimented with various ways to achieve this, and I am
>>confident by now that this would work. However, I would need to
>>reimplement the defmethod and maybe even the defgeneric macro.
> 
> What would you need to reimplement defgeneric for? Do some
> implementations not support specifying a g-f metaclass?

Most of them (with a MOP) accept a g-f metaclass, but many do not accept 
any extra options apart from those defined by ANSI CL. The MOP is also 
vague about how to parse g-f options.


Pascal

-- 
Pascal Costanza               University of Bonn
·········@p-cos.net           Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)