Subject: bug#77725: 31.0.50; Add support for types accepted by `cl-typep' to cl-generic?

From: David Ponce <[email-masked]>
Date: Sun, 13 Apr 2025 18:28:44 +0200

On 2025-04-13 17:53, Stefan Monnier wrote:
>> For instance, if you define an icon type like this:
>>
>> (defgtype icon nil ()
>>    "Builtin icon type."
>>    '(and symbol (satisfies iconp)))
>>
>> (gtype-of 'button)
>> => icon
>> (cl-type-of 'button)
>> => symbol
>>
>> So you cannot have two methods with the same name, one to handle the
>> symbol type, and one to handle the icon type.  I agree, it is a
>> limitation.  Is this your point?
> 
> Kind of.  Note: you can.  It's just that with your current code I expect
> it will misbehave (rather than signal an error).
> 
> BTW, for the above case, your code could recognize that `icon` is
> a subtype of `symbol` and tell that to cl-generic.
> 
>> I wonder if in practice it is really inconvenient, and worth the
>> trouble of complicate more the implementation?
> 
> I don't think I understand what compilations you're talking about, nor
> what kind of inconvenience you're referring to.
> 
>> Isn't it clearer to use different methods for icons and symbols?
>> Aren't these types fundamentally different, and isn't the fact that an
>> icon is a symbol just an implementation choice?
> 
> The question is not whether it's desirable, but whether we can provide
> an implementation that works without too many quirks.  🙂
> 
>>> BTW if you do
>>>       (defgtype cons-car-foo nil ()
>>>         "A cons with a `foo' car."
>>>         `(satisfies ,(lambda (x) (eq (car-safe x) 'foo))))
>>>       (defgtype cons-cdr-foo nil ()
>>>         "A cons with a `foo' cdr."
>>>         `(satisfies ,(lambda (x) (eq (cdr-safe x) 'foo))))
>>> what's the `(gtype-of '(foo . foo))` ?
>>
>> Regarding this point, perhaps it would be possible to use an heuristic
>> like: "in case of conflict, the last defined type is chosen as the
>> most specific"?
> 
> I'm pretty sure some of your users will still be confused when their
> methods are not used, just because some other part of their `cons` cells
> happens to have a value recognized by an unrelated type.
> 
> And of course, they'd probably also be confused if the method that
> handles `cons` is not used for those cons-cells.
> 
>>> Yeah, it's unsatisfactorily intricate, indeed.  It's designed first and
>>> foremost to keep the dispatch "simple and reasonable fast", at the cost
>>> of making `cl-generic-define-generalizer` a very sharp tool.  🙂
>>> I have recently been thinking about how to make it more reliable (which
>>> would also make it more flexible/powerful, allowing the definition of
>>> both `and` and `or` specializers).  I have some vague idea, but there's
>>> no code at all yet, and it might come with some non-trivial tradeoffs
>>> (e.g. preloading the byte-compiler).
>> I can't wait to see this :-)
> 
> I know I wrote "yet", but I have a very long list of "ideas I've had":
> most of those will never become concrete.
> 
> 
>          Stefan
> 

Hi Stefan

Thank you again for your very valuable input.
I am afraid, this discussion just confirms that I don't understand well
enough how cl-generic works, and how it can be improved the correct way :-(

Have a nice Sunday.

David