* bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch
@ 2013-06-24 14:29 Stephen Berman
2013-06-25 1:39 ` Stefan Monnier
0 siblings, 1 reply; 5+ messages in thread
From: Stephen Berman @ 2013-06-24 14:29 UTC (permalink / raw)
To: 14702
0. Save the following defun to a file, say foo.el:
(defun baz ()
(interactive)
(catch 'test
(if (called-interactively-p 'any)
(message "interactive")
(message "noninteractive"))))
1. Load foo, then type `M-x baz'.
=> "interactive"
2. M-: (fmakunbound 'baz)
3. Byte-compile foo.el, load the compiled file and type `M-x baz'.
=> "noninteractive"
If in the function `baz' you either remove the `catch' form or replace
(called-interactively-p 'any) by (eq this-command 'baz), and then repeat
the above steps, then the result of both non-compiled and compiled
interactive calls is "interactive".
In GNU Emacs 24.3.50.1 (x86_64-suse-linux-gnu, GTK+ Version 3.4.4)
of 2013-06-22 on rosalinde
Bzr revision: 113135 lekktu@gmail.com-20130622024114-o1weajdmsssio1vk
Windowing system distributor `The X.Org Foundation', version 11.0.11203000
System Description: openSUSE 12.2 (x86_64)
Configured using:
`configure --without-toolkit-scroll-bars CFLAGS=-g3 -O0'
Important settings:
value of $LANG: en_US.UTF-8
value of $XMODIFIERS: @im=local
locale-coding-system: utf-8-unix
default enable-multibyte-characters: t
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch
2013-06-24 14:29 bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch Stephen Berman
@ 2013-06-25 1:39 ` Stefan Monnier
2013-06-25 13:56 ` Stephen Berman
0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2013-06-25 1:39 UTC (permalink / raw)
To: Stephen Berman; +Cc: 14702
> (defun baz ()
> (interactive)
> (catch 'test
> (if (called-interactively-p 'any)
If it hurts, don't do that.
Internally, the byte-compiled form of catch ends up wrapping its body
inside a lambda, so the called-interactively-p test refers to the
implicit lambda added, rather than to the enclosing function
you defined.
It would be good to avoid this intermediate lambda for performance
reasons (which would incidentally also fix this particular issue), but
in the mean time (and more generally) either avoid
called-interactively-p (pass an extra argument instead), or avoid
placing it "deep" within your function (e.g. inside
a catch/unwind-protect/condition-case/save-foobar/...).
Stefan
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch
2013-06-25 1:39 ` Stefan Monnier
@ 2013-06-25 13:56 ` Stephen Berman
2013-06-25 14:04 ` Stefan Monnier
0 siblings, 1 reply; 5+ messages in thread
From: Stephen Berman @ 2013-06-25 13:56 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 14702
On Mon, 24 Jun 2013 21:39:21 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> (defun baz ()
>> (interactive)
>> (catch 'test
>> (if (called-interactively-p 'any)
>
> If it hurts, don't do that.
> Internally, the byte-compiled form of catch ends up wrapping its body
> inside a lambda,
Ah, knowing that I now understand what the disassembled code shows,
which I didn't before, even though there's a hint to that effect in the
Emacs Lisp manual (i.e., "If it is a lambda expression, `disassemble'
compiles it and disassembles the resulting compiled code.").
> so the called-interactively-p test refers to the
> implicit lambda added, rather than to the enclosing function
> you defined.
>
> It would be good to avoid this intermediate lambda for performance
> reasons (which would incidentally also fix this particular issue), but
> in the mean time (and more generally) either avoid
> called-interactively-p (pass an extra argument instead), or avoid
> placing it "deep" within your function (e.g. inside
> a catch/unwind-protect/condition-case/save-foobar/...).
At the moment I don't see a way to do either of these: I can't use an
extra argument, because the command where I use called-interactively-p
already uses a prefix argument for another purpose; and I don't see an
alternative to something like `catch', because I need to stop execution
of the command in the middle, when certain conditions obtain (this is my
current fix for the recently reported Todo mode bug -- though I'm trying
to come up with something better, so maybe `catch' will then be
dispensable).
But maybe I can use (eq this-command '<COMMAND-NAME>) instead of
called-interactively-p, since evidently this-command is not effected by
the intervening lambda. Or can that sexp ever return t when
<COMMAND-NAME> is not called interactively?
Steve Berman
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch
2013-06-25 13:56 ` Stephen Berman
@ 2013-06-25 14:04 ` Stefan Monnier
2013-06-25 14:18 ` Stephen Berman
0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2013-06-25 14:04 UTC (permalink / raw)
To: Stephen Berman; +Cc: 14702
> At the moment I don't see a way to do either of these: I can't use an
> extra argument, because the command where I use called-interactively-p
> already uses a prefix argument for another purpose; and I don't see an
I don't see the relationship:
(defun foo (prefix &optional interactive)
"Blabla."
(interactive "P\np")
... (catch ... (if interactive ...) ...) ...)
> alternative to something like `catch', because I need to stop execution
I didn't say not to use `catch', I said not to use
called-interactively-p inside `catch'. E.g.
(let ((interactive (called-interactively-p 'any)))
...
(catch ... (if interactive ...) ...) ...)
Stefan
^ permalink raw reply [flat|nested] 5+ messages in thread
* bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch
2013-06-25 14:04 ` Stefan Monnier
@ 2013-06-25 14:18 ` Stephen Berman
0 siblings, 0 replies; 5+ messages in thread
From: Stephen Berman @ 2013-06-25 14:18 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 14702
On Tue, 25 Jun 2013 10:04:51 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> At the moment I don't see a way to do either of these: I can't use an
>> extra argument, because the command where I use called-interactively-p
>> already uses a prefix argument for another purpose; and I don't see an
>
> I don't see the relationship:
>
> (defun foo (prefix &optional interactive)
> "Blabla."
> (interactive "P\np")
> ... (catch ... (if interactive ...) ...) ...)
D'oh! I forgot about that possibility...
>> alternative to something like `catch', because I need to stop execution
>
> I didn't say not to use `catch', I said not to use
> called-interactively-p inside `catch'. E.g.
>
> (let ((interactive (called-interactively-p 'any)))
> ...
> (catch ... (if interactive ...) ...) ...)
D'oh^2! Obviously I'm not very clear-headed right now...
Thanks.
Steve Berman
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-06-25 14:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-24 14:29 bug#14702: 24.3.50; Byte-compiling called-interactively-p inside catch Stephen Berman
2013-06-25 1:39 ` Stefan Monnier
2013-06-25 13:56 ` Stephen Berman
2013-06-25 14:04 ` Stefan Monnier
2013-06-25 14:18 ` Stephen Berman
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).