unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
@ 2014-06-29 14:13 Drew Adams
  2014-06-29 15:01 ` Michael Heerdegen
  0 siblings, 1 reply; 23+ messages in thread
From: Drew Adams @ 2014-06-29 14:13 UTC (permalink / raw)
  To: 17871

This node says this:

  One exception: if the interactive
  spec of FUNCTION is a function (rather than an expression or a
  string), then the interactive spec of the combined function will
  be a call to that function with as sole argument the interactive
  spec of the original function.

I'm unfamiliar with an interactive spec (i.e., the SPEC in
(interactive SPEC) being a function, rather than an expression or
a string.  I cannot find anything else in the manual that refers to
this possibility.  Please document this feature.  Or if it is in
fact documented already, please cross-reference that location from
this node.

(If SPEC cannot be a function, which has been my understanding,
then please correct the statement that it can be.)


In GNU Emacs 24.4.50.1 (i686-pc-mingw32)
 of 2014-06-17 on ODIEONE
Bzr revision: 117359 monnier@iro.umontreal.ca-20140617193358-2t1nl1te9gc2mqrx
Windowing system distributor `Microsoft Corp.', version 6.1.7601
Configured using:
 `configure --prefix=/c/Devel/emacs/snapshot/trunk
 --enable-checking=yes,glyphs 'CFLAGS=-O0 -g3'
 LDFLAGS=-Lc:/Devel/emacs/lib 'CPPFLAGS=-DGC_MCHECK=1
 -Ic:/Devel/emacs/include''





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-29 14:13 bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function? Drew Adams
@ 2014-06-29 15:01 ` Michael Heerdegen
  2014-06-29 15:52   ` Drew Adams
  0 siblings, 1 reply; 23+ messages in thread
From: Michael Heerdegen @ 2014-06-29 15:01 UTC (permalink / raw)
  To: Drew Adams; +Cc: 17871

Drew Adams <drew.adams@oracle.com> writes:

> This node says this:
>
>   One exception: if the interactive
>   spec of FUNCTION is a function (rather than an expression or a
>   string), then the interactive spec of the combined function will
>   be a call to that function with as sole argument the interactive
>   spec of the original function.
>
> I'm unfamiliar with an interactive spec (i.e., the SPEC in
> (interactive SPEC) being a function, rather than an expression or
> a string.  I cannot find anything else in the manual that refers to
> this possibility.  Please document this feature.  Or if it is in
> fact documented already, please cross-reference that location from
> this node.

AFAIK using a function as interactive SPEC is only useful for functions
used as advices, so there is nothing to cross-reference.  And the node
explains well how it works.  What information is missing in your
opinion?

Michael.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-29 15:01 ` Michael Heerdegen
@ 2014-06-29 15:52   ` Drew Adams
  2014-06-29 22:03     ` Stefan Monnier
  2014-06-30 20:48     ` Michael Heerdegen
  0 siblings, 2 replies; 23+ messages in thread
From: Drew Adams @ 2014-06-29 15:52 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: 17871

> AFAIK using a function as interactive SPEC is only useful for functions
> used as advices, so there is nothing to cross-reference.  And the node
> explains well how it works.  What information is missing in your
> opinion?

The doc about interactive specs says nothing (that I have found)
about the possibility of the spec being a function.  On the contrary,
it says that it must be a string or a sexp whose evaluation returns
a list (of argument values).  That *excludes* a sexp that returns
a function.

Even if, as you say, using a functional SPEC has only the one
use case (advising), the doc about interactive specs should call
out both (a) the *possibility* of a functional SPEC and (b) the
fact that this *can only be used for advising*.

And yes, that updated doc about interactive specs should then
cross-reference the doc about using a functional interactive spec
for advising - and vice versa.

The doc that says what an interactive spec is and what forms it
can take (e.g. node `Defining Commands' and its children,
particularly `Using Interactive') currently excludes the
possibility of it being a function.  So it makes no sense for
some other (far removed) node to now talk casually of *using*
that possibility.  If you cannot define an interactive spec as a
function (as the doc indicates) then how can you use it as such?

This is the result of introducing a new feature without properly
documenting it.  Hopefully this will be corrected.

And that points to a second bug involved here: this new feature
(the possibility of a functional interactive spec) is not even
mentioned in NEWS.  The addition of `nadvice.el' is mentioned,
but not the change to what an interactive spec is and what
forms it can take.

Furthermore, there is nothing in NEWS about `defadvice' being
deprecated (or whatever its official limbo status is now).

Instead, there is an entry that mentions a new limitation on it:
"`defadvice' does not honor the `freeze' flag and cannot advise
special-forms any more."  And that suggests just the opposite
of its being deprecated.

(And FWIW, stripping the manual of its doc for `defadvice' was
quite unwise.)





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-29 15:52   ` Drew Adams
@ 2014-06-29 22:03     ` Stefan Monnier
  2014-06-29 23:49       ` Drew Adams
  2014-06-30 20:48     ` Michael Heerdegen
  1 sibling, 1 reply; 23+ messages in thread
From: Stefan Monnier @ 2014-06-29 22:03 UTC (permalink / raw)
  To: Drew Adams; +Cc: Michael Heerdegen, 17871

> That *excludes* a sexp that returns a function.

We're not talking about a sexp that returns a function, but a sexp which
*is* a function.


        Stefan





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-29 22:03     ` Stefan Monnier
@ 2014-06-29 23:49       ` Drew Adams
  0 siblings, 0 replies; 23+ messages in thread
From: Drew Adams @ 2014-06-29 23:49 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Michael Heerdegen, 17871

> > That *excludes* a sexp that returns a function.
> 
> We're not talking about a sexp that returns a function, but a sexp which
> *is* a function.

What does that change?  The `interactive' doc does not cover that
either, AFAICT.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-29 15:52   ` Drew Adams
  2014-06-29 22:03     ` Stefan Monnier
@ 2014-06-30 20:48     ` Michael Heerdegen
  2019-08-04 12:06       ` Lars Ingebrigtsen
  1 sibling, 1 reply; 23+ messages in thread
From: Michael Heerdegen @ 2014-06-30 20:48 UTC (permalink / raw)
  To: Drew Adams; +Cc: 17871

Drew Adams <drew.adams@oracle.com> writes:

> And yes, that updated doc about interactive specs should then
> cross-reference the doc about using a functional interactive spec for
> advising - and vice versa.

Dunno if that would be good.  Although we can with nadvice use
the same syntax for defining pieces of advice as for defining functions,
advices have a different meaning (semantic).  The interactive
specs of advices are not exactly interactive specs in the common sense -
although they look similar, they are related, but different features.

I think a short example would be good.  Also, the term "function" is a
bit unclear here, maybe we should add "a lambda expression or fbound
symbol" or so, to make clear that we don't mean a sexp that returns a
function.

Michael.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2014-06-30 20:48     ` Michael Heerdegen
@ 2019-08-04 12:06       ` Lars Ingebrigtsen
  2019-08-04 12:45         ` Michael Heerdegen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-04 12:06 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Stefan Monnier, 17871

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Dunno if that would be good.  Although we can with nadvice use
> the same syntax for defining pieces of advice as for defining functions,
> advices have a different meaning (semantic).  The interactive
> specs of advices are not exactly interactive specs in the common sense -
> although they look similar, they are related, but different features.

Yes, I think the description of this wrinkle of the interactive spec in
advised functions belongs in this section of the manual and not in the
normal `interactive' doc string.

> I think a short example would be good.  Also, the term "function" is a
> bit unclear here, maybe we should add "a lambda expression or fbound
> symbol" or so, to make clear that we don't mean a sexp that returns a
> function.

I've now added the "a lambda ..." etc to the manual, but while trying to
find an example to use here, I came up short.

But the manual says

To interpret the spec received as argument, use
@code{advice-eval-interactive-spec}.

so I went looking for that function, and what I found was slightly
puzzling:

(defun advice-eval-interactive-spec (spec)
  "Evaluate the interactive spec SPEC."
  (cond
   ((stringp spec)
    ;; There's no direct access to the C code (in call-interactively) that
    ;; processes those specs, but that shouldn't stop us, should it?
    ;; FIXME: Despite appearances, this is not faithful: SPEC and
    ;; (advice-eval-interactive-spec SPEC) will behave subtly differently w.r.t
    ;; command-history (and maybe a few other details).
    (call-interactively `(lambda (&rest args) (interactive ,spec) args)))
   ;; ((functionp spec) (funcall spec))
   (t (eval spec))))

The functionp case is commented out?  This was apparently done in
1668ea9062e (in 2012!) by Stefan while rewriting this stuff.

If nobody has missed this since 2012...  perhaps it should just be
removed?  

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





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-04 12:06       ` Lars Ingebrigtsen
@ 2019-08-04 12:45         ` Michael Heerdegen
  2019-08-04 12:56           ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Michael Heerdegen @ 2019-08-04 12:45 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Stefan Monnier, 17871

Lars Ingebrigtsen <larsi@gnus.org> writes:

> (defun advice-eval-interactive-spec (spec)
>   "Evaluate the interactive spec SPEC."
>   (cond
>    ((stringp spec)
>     ;; There's no direct access to the C code (in call-interactively) that
>     ;; processes those specs, but that shouldn't stop us, should it?
>     ;; FIXME: Despite appearances, this is not faithful: SPEC and
>     ;; (advice-eval-interactive-spec SPEC) will behave subtly differently w.r.t
>     ;; command-history (and maybe a few other details).
>     (call-interactively `(lambda (&rest args) (interactive ,spec) args)))
>    ;; ((functionp spec) (funcall spec))
>    (t (eval spec))))
>
> The functionp case is commented out?  This was apparently done in
> 1668ea9062e (in 2012!) by Stefan while rewriting this stuff.
>
> If nobody has missed this since 2012...  perhaps it should just be
> removed?

I guess SPEC is never functionp, at least after that change.  By
skimming over the code, the

  (interactive (lambda (old-interactive-form) ...))

case is transformed by `advice--make-interactive-form' to something else
that is not a function, and apart from this, interactive specs are never
functionp.

Michael.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-04 12:45         ` Michael Heerdegen
@ 2019-08-04 12:56           ` Lars Ingebrigtsen
  2019-08-04 15:15             ` Štěpán Němec
  2019-08-05  6:26             ` Michael Heerdegen
  0 siblings, 2 replies; 23+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-04 12:56 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Stefan Monnier, 17871

Michael Heerdegen <michael_heerdegen@web.de> writes:

> I guess SPEC is never functionp, at least after that change.  By
> skimming over the code, the
>
>   (interactive (lambda (old-interactive-form) ...))
>
> case is transformed by `advice--make-interactive-form' to something else
> that is not a function, and apart from this, interactive specs are never
> functionp.

Ah, right.  But since `advice--make-interactive-form' does the
transform, then I guess functionp interactive specs in advice is still
allowed?

And then we should add an example in the manual, I think.  Anybody got
one?  :-)

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





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-04 12:56           ` Lars Ingebrigtsen
@ 2019-08-04 15:15             ` Štěpán Němec
  2019-08-05  6:26             ` Michael Heerdegen
  1 sibling, 0 replies; 23+ messages in thread
From: Štěpán Němec @ 2019-08-04 15:15 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Michael Heerdegen, 17871, Stefan Monnier, Juri Linkov

On Sun, 04 Aug 2019 14:56:57 +0200
Lars Ingebrigtsen wrote:

> Ah, right.  But since `advice--make-interactive-form' does the
> transform, then I guess functionp interactive specs in advice is still
> allowed?
>
> And then we should add an example in the manual, I think.  Anybody got
> one?  :-)

There's one by Juri Linkov (Cc'd) on the *Help* variable edit thread:

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36826#41

I was jumping through similar hoops recently myself, and the result
wasn't any prettier...

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-04 12:56           ` Lars Ingebrigtsen
  2019-08-04 15:15             ` Štěpán Němec
@ 2019-08-05  6:26             ` Michael Heerdegen
  2019-08-05  8:44               ` Štěpán Němec
  2019-08-05  9:21               ` Lars Ingebrigtsen
  1 sibling, 2 replies; 23+ messages in thread
From: Michael Heerdegen @ 2019-08-05  6:26 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Stefan Monnier, 17871

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Michael Heerdegen <michael_heerdegen@web.de> writes:
>
> > I guess SPEC is never functionp, at least after that change.  By
> > skimming over the code, the
> >
> >   (interactive (lambda (old-interactive-form) ...))
> >
> > case is transformed by `advice--make-interactive-form' to something else
> > that is not a function, and apart from this, interactive specs are never
> > functionp.
>
> Ah, right.  But since `advice--make-interactive-form' does the
> transform, then I guess functionp interactive specs in advice is still
> allowed?

Would surprise me if not.

> And then we should add an example in the manual, I think.  Anybody got
> one?  :-)

If nobody suggests a nice one (the one by Štěpán is not bad), we could
construct one deriving from the following typical use cases:

(1) Changing how input is read for a single command.  Štěpán's example
is such a thing.  Make individual commands use helm or ido or icicles,
or single command not use helm or ido or icicles although the according
mode is turned on, is a use case.

(2) Enhance a command to accept an additional argument.  The interactive
form of the :around advice will reuse the interactive form of the
original command to read in the arguments the original command accepts,
read in the additional argument, and return the combined list.

(3) Make input reading saver: If certain input for a command is
potentially dangerous or error-prone, one could change it to add tests/
ask for confirmation, or run it in a loop y (confirm) n (abort) r
(retry, give new input).


I think (2) could provide a nice playground example if no one suggests
something nice real-life.

Michael.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-05  6:26             ` Michael Heerdegen
@ 2019-08-05  8:44               ` Štěpán Němec
  2019-08-05  9:21               ` Lars Ingebrigtsen
  1 sibling, 0 replies; 23+ messages in thread
From: Štěpán Němec @ 2019-08-05  8:44 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Lars Ingebrigtsen, Stefan Monnier, 17871

On Mon, 05 Aug 2019 08:26:03 +0200
Michael Heerdegen wrote:

> [...] the following typical use cases:
>
> (1) Changing how input is read for a single command.  Štěpán's example
> is such a thing.  Make individual commands use helm or ido or icicles,
> or single command not use helm or ido or icicles although the according
> mode is turned on, is a use case.
>
> (2) Enhance a command to accept an additional argument.  The interactive
> form of the :around advice will reuse the interactive form of the
> original command to read in the arguments the original command accepts,
> read in the additional argument, and return the combined list.
>
> (3) Make input reading saver: If certain input for a command is
> potentially dangerous or error-prone, one could change it to add tests/
> ask for confirmation, or run it in a loop y (confirm) n (abort) r
> (retry, give new input).

Thank you for the write-up! I for one would really appreciate if all of
that went into the manual, ideally with examples (not only one). I was
now able to simplify my originally overcomplicated real-life example to
the following, but it wasn't as easy as I would have liked back then to
figure it out perusing the existing documentation (I had to look at the
code as well):

Say you use `ivy-mode' for minibuffer completion, as well as
`ivy-prescient-mode' from the `prescient' package, which modifies the
way ivy sorts completion candidates. But there is a command `my-command'
where `ivy-prescient-mode' really gets in the way instead of helping, so
you want to disable it for that single command. Unfortunately, the
following naïve version does not work:

(defun my-no-prescient-advice (orig &rest args)
  (let ((enabled ivy-prescient-mode))
    (unwind-protect
        (progn (when enabled (ivy-prescient-mode -1))
               (apply orig args))
      (when enabled (ivy-prescient-mode 1)))))

(advice-add 'my-command :around #'my-no-prescient-advice)

because it has no effect on the `interactive' form of `my-command' [BTW,
I find this very strange, so if that's really a feature it should IMO be
mentioned prominently in the documentation].

You have to do something like the following instead:

(defun my-no-prescient-advice (orig &rest args)
  (interactive (lambda (spec)
                 (let ((enabled ivy-prescient-mode))
                   (unwind-protect
                       (progn (when enabled (ivy-prescient-mode -1))
                              (advice-eval-interactive-spec spec))
                     (when enabled (ivy-prescient-mode 1))))))
  (apply orig args))

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-05  6:26             ` Michael Heerdegen
  2019-08-05  8:44               ` Štěpán Němec
@ 2019-08-05  9:21               ` Lars Ingebrigtsen
  2019-08-18 12:26                 ` Michael Heerdegen
  1 sibling, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-05  9:21 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Stefan Monnier, 17871

Michael Heerdegen <michael_heerdegen@web.de> writes:

> If nobody suggests a nice one (the one by Štěpán is not bad), we could
> construct one deriving from the following typical use cases:

> (2) Enhance a command to accept an additional argument.  The interactive
> form of the :around advice will reuse the interactive form of the
> original command to read in the arguments the original command accepts,
> read in the additional argument, and return the combined list.

I think an example along these lines would be very nice for the manual.

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





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-05  9:21               ` Lars Ingebrigtsen
@ 2019-08-18 12:26                 ` Michael Heerdegen
  2019-08-18 13:32                   ` Štěpán Němec
  0 siblings, 1 reply; 23+ messages in thread
From: Michael Heerdegen @ 2019-08-18 12:26 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Štěpán Němec, Stefan Monnier, 17871

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Michael Heerdegen <michael_heerdegen@web.de> writes:
>
> > If nobody suggests a nice one (the one by Štěpán is not bad), we could
> > construct one deriving from the following typical use cases:
>
> > (2) Enhance a command to accept an additional argument.  The interactive
> > form of the :around advice will reuse the interactive form of the
> > original command to read in the arguments the original command accepts,
> > read in the additional argument, and return the combined list.
>
> I think an example along these lines would be very nice for the manual.

Štěpán, any nice idea which command I could use to write the example?

Michael.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-18 12:26                 ` Michael Heerdegen
@ 2019-08-18 13:32                   ` Štěpán Němec
  2019-08-18 23:06                     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Štěpán Němec @ 2019-08-18 13:32 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Lars Ingebrigtsen, Stefan Monnier, 17871

On Sun, 18 Aug 2019 14:26:38 +0200
Michael Heerdegen wrote:

>> > (2) Enhance a command to accept an additional argument.  The interactive
>> > form of the :around advice will reuse the interactive form of the
>> > original command to read in the arguments the original command accepts,
>> > read in the additional argument, and return the combined list.
>>
>> I think an example along these lines would be very nice for the manual.
>
> Štěpán, any nice idea which command I could use to write the example?

Well, the closest I see in my init is this (in fact I have been doing it
differently and more uglily, but now I see this is simpler):

(defun my-compose-mail-advice (orig &rest args)
  "Read From: address interactively."
  (interactive (lambda (spec)
                 (let* ((user-mail-address
                         (completing-read "From: " '("one.address@example.net"
                                                     "alternative.address@example.net")))
                        (from (message-make-from user-full-name
                                                 user-mail-address))
                        (spec (advice-eval-interactive-spec spec)))
                   ;; notmuch doesn't understand "From", it has to be a symbol
                   (push (cons 'From from) (nth 2 spec))
                   spec)))
  (apply orig args))

(advice-add 'compose-mail :around #'my-compose-mail-advice)

One might argue that, given the simple nature of `compose-mail' original
interactive spec (no actual user interaction), constructing a plain list
disregarding the original would suffice here, but it would really be
almost the same.

I'm sure one could come up with better examples, but I can't think of
anything off the top of my head.

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-18 13:32                   ` Štěpán Němec
@ 2019-08-18 23:06                     ` Lars Ingebrigtsen
  2019-08-18 23:50                       ` Štěpán Němec
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-18 23:06 UTC (permalink / raw)
  To: Štěpán Němec; +Cc: Michael Heerdegen, Stefan Monnier, 17871

Štěpán Němec <stepnem@gmail.com> writes:

> Well, the closest I see in my init is this (in fact I have been doing it
> differently and more uglily, but now I see this is simpler):
>
> (defun my-compose-mail-advice (orig &rest args)
>   "Read From: address interactively."
>   (interactive (lambda (spec)
>                  (let* ((user-mail-address
>                          (completing-read "From: " '("one.address@example.net"
>                                                      "alternative.address@example.net")))
>                         (from (message-make-from user-full-name
>                                                  user-mail-address))
>                         (spec (advice-eval-interactive-spec spec)))
>                    ;; notmuch doesn't understand "From", it has to be a symbol
>                    (push (cons 'From from) (nth 2 spec))
>                    spec)))
>   (apply orig args))
>
> (advice-add 'compose-mail :around #'my-compose-mail-advice)

That's a good example.  I've now added it to the trunk with some slight
modifications.

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





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-18 23:06                     ` Lars Ingebrigtsen
@ 2019-08-18 23:50                       ` Štěpán Němec
  2019-08-19  0:35                         ` Drew Adams
  2019-08-20 21:49                         ` Juri Linkov
  0 siblings, 2 replies; 23+ messages in thread
From: Štěpán Němec @ 2019-08-18 23:50 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Michael Heerdegen, Stefan Monnier, 17871

Lars Ingebrigtsen wrote:

> Štěpán Němec <stepnem@gmail.com> writes:

[...]

>> (advice-add 'compose-mail :around #'my-compose-mail-advice)
>
> That's a good example.  I've now added it to the trunk with some slight
> modifications.

Thanks (and let me use this opportunity to express sincere admiration
and gratitude for your general bug slaying performance and stamina).

If that really improves the substance of this bug report only Drew can
say I guess.

I for one still think that a more detailed explanation similar to
Michael's from a previous mail[1] would be helpful, ideally with more
examples.

And although I have managed to clarify a few points myself thanks to
this conversation, my personal conundrum[2] remains unanswered: why does
a simple advice have no effect on the interactive spec of the function
being advised, and is that really a feature? But perhaps that's for
another thread.

[1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17871#35
[2] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17871#38

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-18 23:50                       ` Štěpán Němec
@ 2019-08-19  0:35                         ` Drew Adams
  2019-08-20 21:49                         ` Juri Linkov
  1 sibling, 0 replies; 23+ messages in thread
From: Drew Adams @ 2019-08-19  0:35 UTC (permalink / raw)
  To: Štěpán Němec, Lars Ingebrigtsen
  Cc: Michael Heerdegen, Stefan Monnier, 17871

> >> (advice-add 'compose-mail :around #'my-compose-mail-advice)
> >
> > That's a good example.  I've now added it to the trunk with some
> > slight modifications.
> 
> Thanks (and let me use this opportunity to express sincere admiration
> and gratitude for your general bug slaying performance and stamina).
> 
> If that really improves the substance of this bug report only Drew can
> say I guess.
> 
> I for one still think that a more detailed explanation similar to
> Michael's from a previous mail[1] would be helpful, ideally with more
> examples.

+1.

The example will help, no doubt.  But it would also
help to explicitly point out that this use (for
advice) of `interactive' is not the usual one.

What Michael said here:

  Although we can with nadvice use the same syntax
  for defining pieces of advice as for defining functions,
  advices have a different meaning (semantic).  The
  interactive specs of advices are not exactly interactive
  specs in the common sense - although they look similar,
  they are related, but different features.

  I think a short example would be good.  Also, the term
  "function" is a bit unclear here, maybe we should add
  "a lambda expression or fbound symbol" or so, to make
  clear that we don't mean a sexp that returns a function.

> And although I have managed to clarify a few points myself thanks to
> this conversation, my personal conundrum[2] remains unanswered: why
> does a simple advice have no effect on the interactive spec of the 
> function being advised, and is that really a feature? But perhaps
> that's for another thread.

Yes.





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-18 23:50                       ` Štěpán Němec
  2019-08-19  0:35                         ` Drew Adams
@ 2019-08-20 21:49                         ` Juri Linkov
  2019-08-20 22:44                           ` Štěpán Němec
  1 sibling, 1 reply; 23+ messages in thread
From: Juri Linkov @ 2019-08-20 21:49 UTC (permalink / raw)
  To: Štěpán Němec
  Cc: Michael Heerdegen, Lars Ingebrigtsen, Stefan Monnier, 17871

> And although I have managed to clarify a few points myself thanks to
> this conversation, my personal conundrum[2] remains unanswered: why does
> a simple advice have no effect on the interactive spec of the function
> being advised, and is that really a feature? But perhaps that's for
> another thread.

Recently I tried to use an advice to override the default call of
`forward-word' in `org-metaright', but this is impossible to do
because it called by `call-interactively'.  Maybe your case has the
same problem?





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-20 21:49                         ` Juri Linkov
@ 2019-08-20 22:44                           ` Štěpán Němec
  2019-08-21  7:01                             ` Stefan Monnier
  0 siblings, 1 reply; 23+ messages in thread
From: Štěpán Němec @ 2019-08-20 22:44 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Michael Heerdegen, Lars Ingebrigtsen, Stefan Monnier, 17871

On Wed, 21 Aug 2019 00:49:05 +0300
Juri Linkov wrote:

>> And although I have managed to clarify a few points myself thanks to
>> this conversation, my personal conundrum[2] remains unanswered: why does
>> a simple advice have no effect on the interactive spec of the function
>> being advised, and is that really a feature? But perhaps that's for
>> another thread.
>
> Recently I tried to use an advice to override the default call of
> `forward-word' in `org-metaright', but this is impossible to do
> because it called by `call-interactively'.  Maybe your case has the
> same problem?

Not really. The real-life example with commentary is in the cited
message (<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17871#38>), but
a minimal example could be the following:

  (defvar __testvar nil)
  
  (defun __test-command ()
    (interactive (ignore (message "__test-command (interactive): %s" __testvar)))
    (message "__test-command (body): %s" __testvar))
  
  (defun __test-advice (orig &rest args)
    (let ((__testvar t))
      (apply orig args)))
  
  (advice-add '__test-command :around #'__test-advice)

Even with the advice, calling __test-command gives:

  __test-command (interactive): nil
  __test-command (body): t

I'd expect the advice to have effect on the whole function, including
the interactive form.

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-20 22:44                           ` Štěpán Němec
@ 2019-08-21  7:01                             ` Stefan Monnier
  2019-08-21  8:17                               ` Štěpán Němec
  0 siblings, 1 reply; 23+ messages in thread
From: Stefan Monnier @ 2019-08-21  7:01 UTC (permalink / raw)
  To: Štěpán Němec
  Cc: Michael Heerdegen, Lars Ingebrigtsen, Juri Linkov, 17871

>   (defvar __testvar nil)
>   
>   (defun __test-command ()
>     (interactive (ignore (message "__test-command (interactive): %s" __testvar)))
>     (message "__test-command (body): %s" __testvar))
>   
>   (defun __test-advice (orig &rest args)
>     (let ((__testvar t))
>       (apply orig args)))
>   
>   (advice-add '__test-command :around #'__test-advice)
>
> Even with the advice, calling __test-command gives:
>
>   __test-command (interactive): nil
>   __test-command (body): t
>
> I'd expect the advice to have effect on the whole function, including
> the interactive form.

The interactive form is executed to build the args with which the
function will be called (hence your advice is only executed after the
interactive spec), so in order for your code to do what you want,
we'd have to always wrap the interactive spec identically to the body.

Maybe in this case it'd do what you want, but in many other cases
it wouldn't.


        Stefan






^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-21  7:01                             ` Stefan Monnier
@ 2019-08-21  8:17                               ` Štěpán Němec
  2019-08-25 15:51                                 ` Stefan Monnier
  0 siblings, 1 reply; 23+ messages in thread
From: Štěpán Němec @ 2019-08-21  8:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Michael Heerdegen, Lars Ingebrigtsen, Juri Linkov, 17871

On Wed, 21 Aug 2019 03:01:23 -0400
Stefan Monnier wrote:

> The interactive form is executed to build the args with which the
> function will be called (hence your advice is only executed after the
> interactive spec), so in order for your code to do what you want,
> we'd have to always wrap the interactive spec identically to the body.

Thank you! I guess from the implementation POV this is obvious, but I
think this simple use case (wrap a function/command) is one of the most
common around advice usage patterns, and I at least was utterly confused
by the behaviour, so I'd have appreciated very much if this "gotcha" was
documented somewhere (my commented example[1] was intended as possible
material for that, but even simple one-sentence mention would be great
help).

> Maybe in this case it'd do what you want, but in many other cases
> it wouldn't.

Do you mean cases where one might _want_ to only affect the body, not
the interactive form? I can't really imagine anything like that... do
you have anything concrete in mind? The current need to wrap the two
separately really feels like jumping through hoops to me[2], but I guess
dwimmishly auto-wrapping the interactive spec sounds kinda dirty, and
would break those other cases I can't imagine.

[1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17871#38
[2] Juri's example is a good illustration of that:
    https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36826#41

-- 
Štěpán





^ permalink raw reply	[flat|nested] 23+ messages in thread

* bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
  2019-08-21  8:17                               ` Štěpán Němec
@ 2019-08-25 15:51                                 ` Stefan Monnier
  0 siblings, 0 replies; 23+ messages in thread
From: Stefan Monnier @ 2019-08-25 15:51 UTC (permalink / raw)
  To: Štěpán Němec
  Cc: Michael Heerdegen, Lars Ingebrigtsen, Juri Linkov, 17871

>> Maybe in this case it'd do what you want, but in many other cases
>> it wouldn't.
> Do you mean cases where one might _want_ to only affect the body, not
> the interactive form? I can't really imagine anything like that... do
> you have anything concrete in mind?

Hmm... I suggest you try

    grep 'advice-add.*:around' **/*.el

and then look for the matches where the advised function
is interactive.  I haven't looked at all of them, but all those that
I checked wouldn't make sense when applied to the interactive spec.


        Stefan






^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2019-08-25 15:51 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-29 14:13 bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function? Drew Adams
2014-06-29 15:01 ` Michael Heerdegen
2014-06-29 15:52   ` Drew Adams
2014-06-29 22:03     ` Stefan Monnier
2014-06-29 23:49       ` Drew Adams
2014-06-30 20:48     ` Michael Heerdegen
2019-08-04 12:06       ` Lars Ingebrigtsen
2019-08-04 12:45         ` Michael Heerdegen
2019-08-04 12:56           ` Lars Ingebrigtsen
2019-08-04 15:15             ` Štěpán Němec
2019-08-05  6:26             ` Michael Heerdegen
2019-08-05  8:44               ` Štěpán Němec
2019-08-05  9:21               ` Lars Ingebrigtsen
2019-08-18 12:26                 ` Michael Heerdegen
2019-08-18 13:32                   ` Štěpán Němec
2019-08-18 23:06                     ` Lars Ingebrigtsen
2019-08-18 23:50                       ` Štěpán Němec
2019-08-19  0:35                         ` Drew Adams
2019-08-20 21:49                         ` Juri Linkov
2019-08-20 22:44                           ` Štěpán Němec
2019-08-21  7:01                             ` Stefan Monnier
2019-08-21  8:17                               ` Štěpán Němec
2019-08-25 15:51                                 ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).