GNU bug report logs - #14702
24.3.50; Byte-compiling called-interactively-p inside catch

Previous Next

Package: emacs;

Reported by: Stephen Berman <stephen.berman <at> gmx.net>

Date: Mon, 24 Jun 2013 14:30:03 UTC

Severity: minor

Tags: wontfix

Found in version 24.3.50

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 14702 in the body.
You can then email your comments to 14702 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#14702; Package emacs. (Mon, 24 Jun 2013 14:30:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stephen Berman <stephen.berman <at> gmx.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 24 Jun 2013 14:30:05 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.3.50; Byte-compiling called-interactively-p inside catch
Date: Mon, 24 Jun 2013 16:29:23 +0200
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 <at> 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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14702; Package emacs. (Tue, 25 Jun 2013 01:40:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Stephen Berman <stephen.berman <at> gmx.net>
Cc: 14702 <at> debbugs.gnu.org
Subject: Re: bug#14702: 24.3.50;
 Byte-compiling called-interactively-p inside catch
Date: Mon, 24 Jun 2013 21:39:21 -0400
>    (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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14702; Package emacs. (Tue, 25 Jun 2013 13:57:05 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 14702 <at> debbugs.gnu.org
Subject: Re: bug#14702: 24.3.50;
 Byte-compiling called-interactively-p inside catch
Date: Tue, 25 Jun 2013 15:56:13 +0200
On Mon, 24 Jun 2013 21:39:21 -0400 Stefan Monnier <monnier <at> 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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14702; Package emacs. (Tue, 25 Jun 2013 14:05:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Stephen Berman <stephen.berman <at> gmx.net>
Cc: 14702 <at> debbugs.gnu.org
Subject: Re: bug#14702: 24.3.50;
 Byte-compiling called-interactively-p inside catch
Date: Tue, 25 Jun 2013 10:04:51 -0400
> 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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14702; Package emacs. (Tue, 25 Jun 2013 14:19:01 GMT) Full text and rfc822 format available.

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

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 14702 <at> debbugs.gnu.org
Subject: Re: bug#14702: 24.3.50;
 Byte-compiling called-interactively-p inside catch
Date: Tue, 25 Jun 2013 16:18:41 +0200
On Tue, 25 Jun 2013 10:04:51 -0400 Stefan Monnier <monnier <at> 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




bug closed, send any further explanations to 14702 <at> debbugs.gnu.org and Stephen Berman <stephen.berman <at> gmx.net> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sat, 01 Feb 2014 07:46: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. (Sat, 01 Mar 2014 12:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 11 years and 166 days ago.

Previous Next


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