* bug#20420: 25.0.50; eieio methods with optional arguments now fail
@ 2015-04-24 19:28 Vitalie Spinu
2015-04-24 20:42 ` Stefan Monnier
0 siblings, 1 reply; 12+ messages in thread
From: Vitalie Spinu @ 2015-04-24 19:28 UTC (permalink / raw
To: 20420
Hi.
First declare:
(defclass cc-A ()
((a :initform "foo")))
(defgeneric xx (&optional a b))
(defmethod xx ()
(message "default"))
And eval (xx). It works as expected.
Now add
(defmethod xx ((obj cc-A) &optional b)
(message "called on cc-A object"))
and eval (xx) again. It throws (wrong-number-of-arguments (1 . &rest) 0).
It used to work in emacs 24.
Thanks,
Vitalie
In GNU Emacs 25.0.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.12.2)
of 2015-04-13 on galago
Repository revision: 30bcb238c3a53f777c2a4952f51a68df6272cff4
Windowing system distributor `The X.Org Foundation', version 11.0.11600000
System Description: Ubuntu 14.10
Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GCONF GSETTINGS
NOTIFY LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
Important settings:
value of $LC_TIME: en_DK.UTF-8
value of $LANG: en_DK.UTF-8
locale-coding-system: utf-8-unix
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-24 19:28 bug#20420: 25.0.50; eieio methods with optional arguments now fail Vitalie Spinu
@ 2015-04-24 20:42 ` Stefan Monnier
2015-04-24 23:35 ` Vitalie Spinu
0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2015-04-24 20:42 UTC (permalink / raw
To: Vitalie Spinu; +Cc: 20420
> (defgeneric xx (&optional a b))
> (defmethod xx ()
> (message "default"))
Hmmm... I think this really only worked by accident and wasn't
explicitly supported by Emacs-24's doc. And adding support for such
degenerate methods might not be straightforward in eieio-compat.el, so
I'm wondering where you've seen such use, to see how important it is to
provide that level of backward compatibility.
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-24 20:42 ` Stefan Monnier
@ 2015-04-24 23:35 ` Vitalie Spinu
2015-04-25 14:41 ` Stefan Monnier
0 siblings, 1 reply; 12+ messages in thread
From: Vitalie Spinu @ 2015-04-24 23:35 UTC (permalink / raw
To: Stefan Monnier; +Cc: 20420
>>> Stefan Monnier on Fri, 24 Apr 2015 16:42:01 -0400 wrote:
>> (defgeneric xx (&optional a b))
>> (defmethod xx ()
>> (message "default"))
> Hmmm... I think this really only worked by accident and wasn't
> explicitly supported by Emacs-24's doc. And adding support for such
> degenerate methods might not be straightforward in eieio-compat.el, so
> I'm wondering where you've seen such use, to see how important it is to
> provide that level of backward compatibility.
I was using function xx that, when called with no arguments, dispatched
methods with the same name on a local object in the current buffer.
I think this pattern is very general. Especially now with the new
cl-defmethod which supports (eql ...) dispatch. A common pattern would
be to dispatch a method on major-mode or other local variable by simply
defining the dispatcher with the same name and no arguments. In this
sense it's a partial generalization of the mode-local.el.
As we are on this topic how about allowing for implicit dispatch on the
arbitrary context? I mean something along the following lines:
(defun eq-major-mode (mode) (eq mode major-mode))
(defgeneric foo ((implicit eq-major-mode) arg1 arg2) ...)
(defmethod foo ('emacs-lisp-mode arg1 arg2) ...)
The `foo` then should be called only as (foo arg1 arg2) and the dispatch
is done implicitly by (eq 'emacs-lisp-mode major-mode).
A shortcut for a common user case might look like:
(defgeneric foo ((eql major-mode) arg1 arg2) ...)
to mean
(defgeneric foo ((implicit (lambda (obj) (eql major-mode))) arg1 arg2) ...)
This pattern would be a powerful generalization of mode-local.el and
would essentially obsolete classic emacs dispatch mechanism as in
(setq-local indent-line-function xxx-mode-indent-line).
Vitalie
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-24 23:35 ` Vitalie Spinu
@ 2015-04-25 14:41 ` Stefan Monnier
2015-04-25 18:25 ` Vitalie Spinu
0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2015-04-25 14:41 UTC (permalink / raw
To: Vitalie Spinu; +Cc: 20420
>> Hmmm... I think this really only worked by accident and wasn't
>> explicitly supported by Emacs-24's doc. And adding support for such
>> degenerate methods might not be straightforward in eieio-compat.el, so
>> I'm wondering where you've seen such use, to see how important it is to
>> provide that level of backward compatibility.
> I was using function xx that, when called with no arguments, dispatched
> methods with the same name on a local object in the current buffer.
That tells me *how* you used it, not *where*.
> As we are on this topic how about allowing for implicit dispatch on the
> arbitrary context? I mean something along the following lines:
Quoting from cl-generic.el:
;; TODO:
[...]
;; - A way to dispatch on the context (e.g. the major-mode, some global
;; variable, you name it).
[...]
;;; Just for kicks: dispatch on major-mode
;;
;; Here's how you'd use it:
;; (cl-defmethod foo ((x (major-mode text-mode)) y z) ...)
;; And then
;; (foo 'major-mode toto titi)
;;
;; FIXME: Better would be to do that via dispatch on an "implicit argument".
;; E.g. (cl-defmethod foo (y z &context (major-mode text-mode)) ...)
IOW, patch welcome.
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-25 14:41 ` Stefan Monnier
@ 2015-04-25 18:25 ` Vitalie Spinu
2015-04-26 4:02 ` Stefan Monnier
0 siblings, 1 reply; 12+ messages in thread
From: Vitalie Spinu @ 2015-04-25 18:25 UTC (permalink / raw
To: Stefan Monnier; +Cc: 20420
>>> Stefan Monnier on Sat, 25 Apr 2015 10:41:40 -0400 wrote:
> That tells me *how* you used it, not *where*.
I was using it in polymode package for a generic indentation
functionality:
https://github.com/vspinu/polymode/blob/master/polymode-methods.el#L530
>> As we are on this topic how about allowing for implicit dispatch on the
>> arbitrary context? I mean something along the following lines:
> Quoting from cl-generic.el:
> ;; TODO:
> [...]
> ;; - A way to dispatch on the context (e.g. the major-mode, some global
> ;; variable, you name it).
> [...]
> ;;; Just for kicks: dispatch on major-mode
> ;;
> ;; Here's how you'd use it:
> ;; (cl-defmethod foo ((x (major-mode text-mode)) y z) ...)
> ;; And then
> ;; (foo 'major-mode toto titi)
> ;;
> ;; FIXME: Better would be to do that via dispatch on an "implicit argument".
> ;; E.g. (cl-defmethod foo (y z &context (major-mode text-mode)) ...)
Aha. Cool! I will have a look. Is there a more elaborate documentation
somewhere? Particularly I don't see "specializer" and "generalizer"
being properly defined anywhere.
Vitalie
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-25 18:25 ` Vitalie Spinu
@ 2015-04-26 4:02 ` Stefan Monnier
2015-04-26 12:00 ` Vitalie Spinu
2015-05-12 4:19 ` Stefan Monnier
0 siblings, 2 replies; 12+ messages in thread
From: Stefan Monnier @ 2015-04-26 4:02 UTC (permalink / raw
To: Vitalie Spinu; +Cc: 20420
>> That tells me *how* you used it, not *where*.
> I was using it in polymode package for a generic indentation
> functionality:
> https://github.com/vspinu/polymode/blob/master/polymode-methods.el#L530
[ After figuring out that the code now doesn't do that any more and
seeing the old code which does do the "nasty" empty-args defmethod. ]
I see, thanks. At least the "workaround" did not require more code,
and is marginally more efficient to boot.
Looking more closely at the way this was handled in the older EIEIO
code, the semantics are pretty ugly, so it the fact that it worked is
clearly an accident, and reproducing that exact semantics would
be difficult.
> Aha. Cool! I will have a look. Is there a more elaborate documentation
> somewhere?
No, it's more a wishlist item: add support for formal pseudo-arguments
of the form "&context (<exp> <specializer>)".
> Particularly I don't see "specializer" and "generalizer"
> being properly defined anywhere.
"Specializer" is used commonly in CLOS to refer to the "thing" that can
be either a class type or (eql <value>). "Generalizer" is not standard
and refers to a thing that takes a value (the actual argument) and finds
its corresponding specializers (i.e. its type(s)). I took the term from
an article that extended CLOS method-matching. cl-generic.el does not
directly implement that article, but it's fairly similar.
This said, adding support for &context shouldn't need to do very much
with specializers and generalizers (more specifically, shouldn't require
defining new specializers or generalizers).
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-26 4:02 ` Stefan Monnier
@ 2015-04-26 12:00 ` Vitalie Spinu
2015-04-27 4:43 ` Stefan Monnier
2015-05-12 4:19 ` Stefan Monnier
1 sibling, 1 reply; 12+ messages in thread
From: Vitalie Spinu @ 2015-04-26 12:00 UTC (permalink / raw
To: Stefan Monnier; +Cc: 20420
>>> Stefan Monnier on Sun, 26 Apr 2015 00:02:51 -0400 wrote:
>>> That tells me *how* you used it, not *where*.
>> I was using it in polymode package for a generic indentation
>> functionality:
>> https://github.com/vspinu/polymode/blob/master/polymode-methods.el#L530
> [ After figuring out that the code now doesn't do that any more and
> seeing the old code which does do the "nasty" empty-args defmethod. ]
Sorry about that. I wasn't expected you will be interested in so much
detail. I would have been more elaborate.
>> Aha. Cool! I will have a look. Is there a more elaborate documentation
>> somewhere?
> No, it's more a wishlist item: add support for formal pseudo-arguments
> of the form "&context (<exp> <specializer>)".
>> Particularly I don't see "specializer" and "generalizer"
>> being properly defined anywhere.
> "Specializer" is used commonly in CLOS to refer to the "thing" that can
> be either a class type or (eql <value>). "Generalizer" is not standard
> and refers to a thing that takes a value (the actual argument) and finds
> its corresponding specializers (i.e. its type(s)). I took the term from
> an article that extended CLOS method-matching. cl-generic.el does not
> directly implement that article, but it's fairly similar.
This sounds like a more involved version of what Clojure does with
multimethods (also implemented in emacs multi.el package [1])
When Clojure's generic is defined you supply a dispatch function that
takes all actual arguments and returns an object (commonly a
symbol). The returned object is then used directly for dispatch. If I
understand correctly the dispatch function is like your generalizer.
Vitalie
[1] https://github.com/kurisuwhyte/emacs-multi
Better documented at https://github.com/vspinu/emacs-multi
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-26 12:00 ` Vitalie Spinu
@ 2015-04-27 4:43 ` Stefan Monnier
0 siblings, 0 replies; 12+ messages in thread
From: Stefan Monnier @ 2015-04-27 4:43 UTC (permalink / raw
To: Vitalie Spinu; +Cc: 20420
> This sounds like a more involved version of what Clojure does with
> multimethods (also implemented in emacs multi.el package [1])
I didn't know about Clojure's defmulti. It's simple and elegant, I like it.
> If I understand correctly the dispatch function is like
> your generalizer.
Somewhat, yes. It's a bit more complex than that because in CLOS (and
even more so in cl-generic) the code to compute the dispatch value
depends on the actual methods defined, so cl-generic's "generalizers"
are objects which describe which code to use depending on which methods
are defined, and the actual value on which we dispatch is in general not
quite the same as the "premise" (i.e. the "specializer"), so the
generalizer also provides code to compute the specializer from the
dispatch value.
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-04-26 4:02 ` Stefan Monnier
2015-04-26 12:00 ` Vitalie Spinu
@ 2015-05-12 4:19 ` Stefan Monnier
2015-05-12 14:23 ` Vitalie Spinu
1 sibling, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2015-05-12 4:19 UTC (permalink / raw
To: Vitalie Spinu; +Cc: 20420
> No, it's more a wishlist item: add support for formal pseudo-arguments
> of the form "&context (<exp> <specializer>)".
It's now implemented.
We should now remove gui-method and use that instead.
And as you mentioned, it probably (at least partly) obsoletes
define-overloadable-function/define-mode-local-override.
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-05-12 4:19 ` Stefan Monnier
@ 2015-05-12 14:23 ` Vitalie Spinu
2016-05-14 23:01 ` Dmitry Gutov
0 siblings, 1 reply; 12+ messages in thread
From: Vitalie Spinu @ 2015-05-12 14:23 UTC (permalink / raw
To: Stefan Monnier; +Cc: 20420
Awesome!
Your TODO still says:
;; - A way to dispatch on the context (e.g. the major-mode, some global
;; variable, you name it).
>>> Stefan Monnier on Tue, 12 May 2015 00:19:09 -0400 wrote:
>> No, it's more a wishlist item: add support for formal pseudo-arguments
>> of the form "&context (<exp> <specializer>)".
> It's now implemented.
> We should now remove gui-method and use that instead.
> And as you mentioned, it probably (at least partly) obsoletes
> define-overloadable-function/define-mode-local-override.
> Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2015-05-12 14:23 ` Vitalie Spinu
@ 2016-05-14 23:01 ` Dmitry Gutov
2016-05-15 1:55 ` Stefan Monnier
0 siblings, 1 reply; 12+ messages in thread
From: Dmitry Gutov @ 2016-05-14 23:01 UTC (permalink / raw
To: Vitalie Spinu, Stefan Monnier; +Cc: 20420
Hi Vitalie,
On 05/12/2015 05:23 PM, Vitalie Spinu wrote:
>
> Awesome!
>
> Your TODO still says:
>
> ;; - A way to dispatch on the context (e.g. the major-mode, some global
> ;; variable, you name it).
Not anymore, since 62f4ed477ebcbe56087bb1df96340530c84b33a9.
Is there something left to fix in this bug? If not, please close it.
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#20420: 25.0.50; eieio methods with optional arguments now fail
2016-05-14 23:01 ` Dmitry Gutov
@ 2016-05-15 1:55 ` Stefan Monnier
0 siblings, 0 replies; 12+ messages in thread
From: Stefan Monnier @ 2016-05-15 1:55 UTC (permalink / raw
To: 20420-done; +Cc: Dmitry Gutov
> Is there something left to fix in this bug? If not, please close it.
Done, thanks,
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-05-15 1:55 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-24 19:28 bug#20420: 25.0.50; eieio methods with optional arguments now fail Vitalie Spinu
2015-04-24 20:42 ` Stefan Monnier
2015-04-24 23:35 ` Vitalie Spinu
2015-04-25 14:41 ` Stefan Monnier
2015-04-25 18:25 ` Vitalie Spinu
2015-04-26 4:02 ` Stefan Monnier
2015-04-26 12:00 ` Vitalie Spinu
2015-04-27 4:43 ` Stefan Monnier
2015-05-12 4:19 ` Stefan Monnier
2015-05-12 14:23 ` Vitalie Spinu
2016-05-14 23:01 ` Dmitry Gutov
2016-05-15 1:55 ` Stefan Monnier
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.