GNU bug report logs - #47327
28.0.50; (cl-generic) eql specializer not evaluated

Previous Next

Package: emacs;

Reported by: akater <nuclearspace <at> gmail.com>

Date: Mon, 22 Mar 2021 17:20:02 UTC

Severity: normal

Tags: fixed

Found in version 28.0.50

Fixed in version 28.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 47327 in the body.
You can then email your comments to 47327 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Mon, 22 Mar 2021 17:20:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to akater <nuclearspace <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 22 Mar 2021 17:20:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: akater <nuclearspace <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Mon, 22 Mar 2021 17:08:09 +0000
[Message part 1 (text/plain, inline)]
In ~(eql VAL)~ specializer, ~VAL~ should evaluate during evaluation of
the macroexpanded ~cl-defmethod~ form.

For some reason =cl-generic.el= does not do that (it does not evaluate
the specializer form at all).  Here's a hack fix that seems to work for
me but I do not have a deep enough understanding of ~cl-generic~ to
actually suggest it:

#+begin_src emacs-lisp :results none
(cl-defmethod cl-generic-generalizers ((specializer (head cl:eql)))
  "Support for (eql VAL) specializers.
These match if the argument is `eql' to VAL."
  (let ((value (eval (cadr specializer) t)))
    (setf (car specializer) 'eql)
    (puthash value specializer cl--generic-eql-used))
  (list cl--generic-eql-generalizer))
#+end_src


Rationale:

(1) See Common Lisp HyperSpec:

#+begin_quote
The parameter specializer name ~(eql eql-specializer-form)~
indicates that the corresponding argument must be eql to the object
that is the value of ~eql-specializer-form~ for the method to be applicable.
The ~eql-specializer-form~ is evaluated
at the time that the expansion of the defmethod macro is evaluated.
#+end_quote
---
[[http://www.lispworks.com/documentation/HyperSpec/Body/m_defmet.htm][Macro
DEFMETHOD]]


(2) With eql specializer form not evaluated it does not seem possible to
e.g. use a custom method combination, even though ~cl-generic~ informs
that it is possible.  The only way I can think of, is
specializing ~cl-generic-combine-methods~ on the particular generic
function:

#+begin_src emacs-lisp :results none :eval never
(cl-defmethod cl-generic-combine-methods ((generic
                                           (cl:eql
                                            (cl--generic
                                             'my-generic-function)))
                                          methods)
  "Use `my-method-combination' method for generic function `my-generic-function'."
  (my-method-combination generic methods))
#+end_src

which is impossible if the specializer form is not evaluated.


(3) With eql specializer form not evaluated, it is only possible to
dispatch on eql numbers or eql symbols which is needlessly limited.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 23 Mar 2021 23:20:02 GMT) Full text and rfc822 format available.

Message #8 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Wed, 24 Mar 2021 00:19:10 +0100
akater <nuclearspace <at> gmail.com> writes:

> In ~(eql VAL)~ specializer, ~VAL~ should evaluate during evaluation of
> the macroexpanded ~cl-defmethod~ form.

Are you sure that it should?  How is it in Common Lisp?  From the
documentation in Emacs I don't get the clear impression that what you
want is intended.  I don't say that it could not be useful, though.

Regards,

Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 23 Mar 2021 23:43:01 GMT) Full text and rfc822 format available.

Message #11 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: akater <nuclearspace <at> gmail.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 23 Mar 2021 23:32:06 +0000
[Message part 1 (text/plain, inline)]
Michael Heerdegen <michael_heerdegen <at> web.de> writes:

> Are you sure that it should?

I've listed 3 reasons why it should.

> How is it in Common Lisp? 

This is addressed in point (1).
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Wed, 24 Mar 2021 00:24:01 GMT) Full text and rfc822 format available.

Message #14 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Wed, 24 Mar 2021 01:22:49 +0100
akater <nuclearspace <at> gmail.com> writes:

> > How is it in Common Lisp?
>
> This is addressed in point (1).

Indeed, sorry for not reading carefully.  Then I think your request is
valid.  I don't feel competent enough to provide a fix, though.  And I
wonder if fixing this might break existing code that exploits the
current behavior.

Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Fri, 02 Jul 2021 11:37:01 GMT) Full text and rfc822 format available.

Message #17 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: akater <nuclearspace <at> gmail.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Fri, 02 Jul 2021 11:25:18 +0000
[Message part 1 (text/plain, inline)]
How about introducing at least cl:eql specializer, like in my original
post, and announce it to replace eql eventually?  Current behaviour does
not really make sense.

Note that I had to

>    (setf (car specializer) 'eql)

as constructing a new cons did not work for me.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Fri, 16 Jul 2021 03:04:02 GMT) Full text and rfc822 format available.

Message #20 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Fri, 16 Jul 2021 05:03:16 +0200
akater <nuclearspace <at> gmail.com> writes:

> How about introducing at least cl:eql specializer, like in my original
> post, and announce it to replace eql eventually?  Current behaviour does
> not really make sense.

Stefan, could you please maybe take over if you get the chance?

TIA,

Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Fri, 16 Jul 2021 21:01:01 GMT) Full text and rfc822 format available.

Message #23 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Fri, 16 Jul 2021 17:00:17 -0400
> #+begin_quote
> The parameter specializer name ~(eql eql-specializer-form)~
> indicates that the corresponding argument must be eql to the object
> that is the value of ~eql-specializer-form~ for the method to be applicable.
> The ~eql-specializer-form~ is evaluated
> at the time that the expansion of the defmethod macro is evaluated.
> #+end_quote

Oh, indeed, I completely missed that.
That would be a nice improvement.

Could you check to see which code would break if we made this change?

The patch below seems to provide enough backward compatibility, but it
would be nice to improve it so the warning is emitted at compile time
via something like `macroexp-warn-and-return` so we get some kind of
file&line number.


        Stefan


diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 544704be38..6d23537ebd 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -1158,7 +1158,12 @@ cl--generic-eql-generalizer
 (cl-defmethod cl-generic-generalizers ((specializer (head eql)))
   "Support for (eql VAL) specializers.
 These match if the argument is `eql' to VAL."
-  (puthash (cadr specializer) specializer cl--generic-eql-used)
+  (let ((form (cadr specializer)))
+    (puthash (if (or (not (symbolp form)) (macroexp-const-p form))
+                 (eval form t)
+               (message "Quoting obsolete `eql' form: %S" specializer)
+               form)
+             specializer cl--generic-eql-used))
   (list cl--generic-eql-generalizer))
 
 (cl--generic-prefill-dispatchers 0 (eql nil))
diff --git a/test/lisp/emacs-lisp/cl-generic-tests.el b/test/lisp/emacs-lisp/cl-generic-tests.el
index 9312fb44a1..b48a48fb94 100644
--- a/test/lisp/emacs-lisp/cl-generic-tests.el
+++ b/test/lisp/emacs-lisp/cl-generic-tests.el
@@ -56,7 +56,11 @@ cl-generic-test-01-eql
   (should (equal (cl--generic-1 'a nil) '(a)))
   (should (equal (cl--generic-1 4 nil) '("quatre" 4)))
   (should (equal (cl--generic-1 5 nil) '("cinq" 5)))
-  (should (equal (cl--generic-1 6 nil) '("six" a))))
+  (should (equal (cl--generic-1 6 nil) '("six" a)))
+  (defvar cl--generic-fooval 41)
+  (cl-defmethod cl--generic-1 ((_x (eql (+ cl--generic-fooval 1))) _y)
+    "forty-two")
+  (should (equal (cl--generic-1 42 nil) "forty-two")))
 
 (cl-defstruct cl-generic-struct-parent a b)
 (cl-defstruct (cl-generic-struct-child1 (:include cl-generic-struct-parent)) c)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Mon, 19 Jul 2021 21:24:02 GMT) Full text and rfc822 format available.

Message #26 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Mon, 19 Jul 2021 17:22:52 -0400
Stefan Monnier [2021-07-16 17:00:17] wrote:
> Oh, indeed, I completely missed that.
> That would be a nice improvement.

BTW, if we make this change for `eql` it would make a lot of sense to
make the same change for the `head` specializer.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 20 Jul 2021 02:40:01 GMT) Full text and rfc822 format available.

Message #29 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: akater <nuclearspace <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 20 Jul 2021 02:28:12 +0000
[Message part 1 (text/plain, inline)]
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Could you check to see which code would break if we made this change?

I looked for “(eql” and then for “cl-defmethod”, searching for generated
code specifically.

Unless there's less obvious code that generates cl-defmethod forms, it
should all be in the attached patch.

>  (cl-defmethod cl-generic-generalizers ((specializer (head eql)))
>    "Support for (eql VAL) specializers.
>  These match if the argument is `eql' to VAL."
> -  (puthash (cadr specializer) specializer cl--generic-eql-used)
> +  (let ((form (cadr specializer)))
> +    (puthash (if (or (not (symbolp form)) (macroexp-const-p form))
> +                 (eval form t)
> +               (message "Quoting obsolete `eql' form: %S" specializer)
> +               form)
> +             specializer cl--generic-eql-used))
>    (list cl--generic-eql-generalizer))

Which implies, those who want to specialize on a value of symbol x
should write (eql (symbol-value 'x)), right?

This irregularity better be pointed out somewhere; I rarely read Elisp
manual so I'm not sure if it would be appropriate there.  Otherwise,
looks good, provided that it works.  (JFYI, I don't think I will be able
to properly test this patch soon enough.)

Please note that there are two spots in the patch where I'm not sure
what (if anything) should be done;  marked with WARNING.

[signature.asc (application/pgp-signature, inline)]
[0001-Upcoming-changes-to-eql-specializer-use.patch (text/x-diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 03 Aug 2021 16:13:01 GMT) Full text and rfc822 format available.

Message #32 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: akater <nuclearspace <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 03 Aug 2021 16:00:44 +0000
[Message part 1 (text/plain, inline)]
In the new patch, I combined your solution and my fixes to current
cl-defmethod forms.  I also tried to write an appropriate description in
the patch header and in etc/NEWS.

Please note that questionable spots remain, marked with `WARNING:'.

[signature.asc (application/pgp-signature, inline)]
[0001-Evaluate-eql-specializers.patch (text/x-diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 03 Aug 2021 23:03:01 GMT) Full text and rfc822 format available.

Message #35 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: akater <nuclearspace <at> gmail.com>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 03 Aug 2021 19:02:28 -0400
> In the new patch, I combined your solution and my fixes to current
> cl-defmethod forms.  I also tried to write an appropriate description in
> the patch header and in etc/NEWS.

Thanks.

> Please note that questionable spots remain, marked with `WARNING:'.

Your intuition was right (i.e. the code you wrote was the right choice).
I pushed it after removing those warnings as well as commenting out the
compile-time warnings from cl-defmethod (which is useful to move to the
new style but for now would be too annoying for third party packages
which have to maintain compatibility with Emacs<28).


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 10 Aug 2021 12:40:01 GMT) Full text and rfc822 format available.

Message #38 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Madhu <enometh <at> meer.net>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 10 Aug 2021 18:09:46 +0530
[Message part 1 (text/plain, inline)]
`emacs --daemon'
`emacsclient -t'  fails to start with a no matching method error

*ERROR*: No applicable method: frame-creation-function,
 ((vertical-scroll-bars) (height . 32) (width . 80) (client . #<process
 server <3>>) [...]  (window-system) (tty . "/dev/pts/3") (tty-type
 . "xterm-256color"))


The following patch might fix it, but it behaves strangely.  After the
fix (without recompiling the emacs binary) if I stick in a (load-library
"frame") in my .emacs, the method does not appear to be patched.  - I
have to use a graphical `emacsclient -n -c' and then compile/load
frame.el again.

[lisp-frame.el-frame-creation-function-fix-window-system.patch (text/x-diff, inline)]
diff --git a/lisp/frame.el b/lisp/frame.el
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -38,7 +38,7 @@ window-system
   ;; so just use it, and anyway `eql' isn't very useful on cons cells.
   `(window-system ,(if (consp value) value `(eql ',value))))
 
-(cl-defmethod frame-creation-function (params &context (window-system nil))
+(cl-defmethod frame-creation-function (params &context (window-system (eql 'nil)))
   ;; It's tempting to get rid of tty-create-frame-with-faces and turn it into
   ;; this method (i.e. move this method to faces.el), but faces.el is loaded
   ;; much earlier from loadup.el (before cl-generic and even before

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Tue, 10 Aug 2021 13:02:01 GMT) Full text and rfc822 format available.

Message #41 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Christian Albrecht <christian.albrecht <at> mayflower.de>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Tue, 10 Aug 2021 14:56:31 +0200
> `emacs --daemon'
> `emacsclient -t'  fails to start with a no matching method error
>
> *ERROR*: No applicable method: frame-creation-function,
>  ((vertical-scroll-bars) (height . 32) (width . 80) (client . #<process
>  server <3>>) [...]  (window-system) (tty . "/dev/pts/3") (tty-type
>  . "xterm-256color"))

is this, by any chance, related to and fixed by
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49877#28

Cheers,
Christian




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Thu, 19 Aug 2021 11:42:01 GMT) Full text and rfc822 format available.

Message #44 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Madhu <enometh <at> meer.net>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Thu, 19 Aug 2021 17:11:34 +0530
* Christian Albrecht via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <87r1f1jvxz.fsf <at> mayflower.de> :
Wrote on Tue, 10 Aug 2021 14:56:31 +0200:

>> `emacs --daemon'
>> `emacsclient -t'  fails to start with a no matching method error
>>
>> *ERROR*: No applicable method: frame-creation-function,
>>  ((vertical-scroll-bars) (height . 32) (width . 80) (client . #<process
>>  server <3>>) [...]  (window-system) (tty . "/dev/pts/3") (tty-type
>>  . "xterm-256color"))
>
> is this, by any chance, related to and fixed by
> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49877#28

I built master and I am not seeing the problem now, so this bug must
have been fixed.

[Both my analysis above and suggested fix seem to be wrong. I think
the problem was that my init file was requiring etags at some
point, which activated the error.
i.e. emacs --fg-daemon -Q -l etags
and  emacsclient -t
would have reproduced it and not the recipe i gave, sorry]





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#47327; Package emacs. (Thu, 19 Aug 2021 13:11:02 GMT) Full text and rfc822 format available.

Message #47 received at 47327 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Madhu <enometh <at> meer.net>
Cc: 47327 <at> debbugs.gnu.org
Subject: Re: bug#47327: 28.0.50; (cl-generic) eql specializer not evaluated
Date: Thu, 19 Aug 2021 15:10:02 +0200
Madhu <enometh <at> meer.net> writes:

>> is this, by any chance, related to and fixed by
>> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49877#28
>
> I built master and I am not seeing the problem now, so this bug must
> have been fixed.

And it seems like the original issue in this bug report (about making
eql specialisers evaluate) works as it should, so I'm closing this bug
report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Added tag(s) fixed. Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Thu, 19 Aug 2021 13:11:02 GMT) Full text and rfc822 format available.

bug marked as fixed in version 28.1, send any further explanations to 47327 <at> debbugs.gnu.org and akater <nuclearspace <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Thu, 19 Aug 2021 13:11:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 17 Sep 2021 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 215 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.