(It's (define-method (f #:key foo) ...).)

This is a valid point. Certainly there should be unambiguous rules so that
we know which method should be selected. (I planned to examine this aspect
before applying my patch to Guile. I was just eager to share what I had
done in order to collect opinions before putting too much effort into it.)

In this case, I would say that positional *should* win since it is most
specific with regards to the specifiers.

The patch I posted actually doesn't result in this, but it could be easily
fixed with a change based on the following consideration:

The motivation for having what you call the "major limitation" of not doing
type dispatch on keyword arguments in GOOPS or CLOS is to strike a
reasonable balance with regards to the complexity of implementation (and
cognitive load for the user, I guess :). In the future, if we come up with
a conceptually simple picture of how to regard method precedence in the
light of typed keyword arguments and also see that this doesn't make the
implementation overly complicated, we can consider extending the
functionality in this direction.

CLOS has a fixed number of required arguments per generic function.  So, in
CLOS it isn't possible to come up with two allowed methods where the order
of dispatch is unclear.

We loosed that up in GOOPS and allow varying number of arguments (which is
a Good Thing). So, you are right that we need to come up with rules that
make the order of dispatch clear.

I propose that the simplest rule which corresponds to restricting type
dispatch to non-keyword arguments is to define the specializer list of
every method with keyword formals like this:

Method formals: ((<F1> <TYPE1>) ... <KEYWORD> ...)

results in

Specializer list: (<TYPE1> ... . <top>)

So

  (method ((x <integer>) . y) ...)

will have the same specializers as

  (method* ((x <integer>) #:key z) ...)

With this definition, positional above will win. In my patch, this
corresponds to changing #''() to #'<top> in the computation of specializers
for keyword methods.

Meanwhile, I've found a further bug in my patch: We need to consider
keyword arguments in re-definition in methods. Fixed now in my still
private code.

Also, I should add that I now lean towards supplying the keyword
functionality in additional syntax method* and define-method*, and keep the
semantics for method and define-method as is.

Best regards,
Mikael

On Sat, Nov 23, 2024 at 4:49 PM Maxime Devos <maximede...@telenet.be> wrote:

> >Well, these particular examples aren't valid since GOOPS doesn't allow
> type specifiers for keyword arguments. (It's the same in CLOS.) Type
> dispatch is done *only* on the required arguments.
>
>
>
> That’s a shame, it should support them IMO, it’s a major limitation if it
> doesn’t.
>
>
>
> A variant with untyped keyword arguments:
>
>
>
> (define-method (f (a <keyword>) (b <symbol>))
>
>   (pk 'positional))
>
>
>
> (define-method (f (#:key foo))
>
>   (pk 'optional-keyword foo))
>
>
>
> (f #:foo 'bar)
>
>
>
> Who should win? Both are a quite specific match.
>
>
>
> Best regards,
>
> Maxime Devos
>

Reply via email to