Subject: bug#37461: define-generic doesn't promote equal? to generic

From: Mikael Djurfeldt <[email-masked]>
Date: Sat, 28 Sep 2019 18:51:43 +0200

On Mon, Sep 23, 2019 at 5:01 PM Mikael Djurfeldt <[email-masked]>
wrote:

>
>   (define-method (equal? (a <string>) (b <string>)) ...)
>
> on the other hand, means that you want to *extend* the current behavior of
> equal? with a specialization to two strings. The method is then added to
> equal?, which in guile-1.8 was from scratch a "primitive-generic".
>
> Actually, this is misguided. I should have examined this problem more
carefully, and also read your later emails more carefully.

You see, I was under the impression that primitive-generic capability had
been removed for equal?. It has not. It's only the printed representation
which has changed.

Your bug report contains two problems. One concerns why define-generic
doesn't create a new generic. I believe this is an intentional or
unintentional change at some version. The other problem concerns the
dispatch rules for primitive generics.

You are right that the dispatch rules are special for primitive generics.
The purpose of primitive generics is to get around any performance penalty
for standard behavior, so primitive generics first try standard dispatch.
Then, if that fails, GOOPS method dispatch is used. The standard behavior
of equal? is to simply return #t when applied to a single argument
regardless of type. This is the explanation why you get #t for (equal?
<foo>).

One way to view this is that the dispatch of primitive-generics is
partially constrained.