From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Richard Stallman Newsgroups: gmane.emacs.devel Subject: Re: Brittleness of called-interactively-p Date: Sun, 12 Jul 2015 17:59:22 -0400 Message-ID: References: <871tgeufzt.fsf@gmail.com> Reply-To: rms@gnu.org NNTP-Posting-Host: plane.gmane.org Content-Type: text/plain; charset=Utf-8 X-Trace: ger.gmane.org 1436738380 4796 80.91.229.3 (12 Jul 2015 21:59:40 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 12 Jul 2015 21:59:40 +0000 (UTC) Cc: emacs-devel@gnu.org To: Dmitri Paduchikh Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jul 12 23:59:31 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZEPHX-0003wY-8K for ged-emacs-devel@m.gmane.org; Sun, 12 Jul 2015 23:59:31 +0200 Original-Received: from localhost ([::1]:52086 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZEPHW-0004pH-PD for ged-emacs-devel@m.gmane.org; Sun, 12 Jul 2015 17:59:30 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59219) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZEPHT-0004oN-4e for emacs-devel@gnu.org; Sun, 12 Jul 2015 17:59:28 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZEPHR-0002go-M2 for emacs-devel@gnu.org; Sun, 12 Jul 2015 17:59:27 -0400 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:42484) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZEPHO-0002fh-Kf; Sun, 12 Jul 2015 17:59:22 -0400 Original-Received: from rms by fencepost.gnu.org with local (Exim 4.82) (envelope-from ) id 1ZEPHO-0003iL-5p; Sun, 12 Jul 2015 17:59:22 -0400 In-reply-to: <871tgeufzt.fsf@gmail.com> (message from Dmitri Paduchikh on Sun, 12 Jul 2015 10:00:54 +0500) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:187840 Archived-At: [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > This function is very brittle, it may fail to return the intended result > when the code is debugged, advised, or instrumented in some form. Some > macros and special forms (such as `condition-case') may also sometimes > wrap their bodies in a `lambda', so any call to `called-interactively-p' > from those bodies will indicate whether that lambda (rather than the > surrounding function) was called interactively. This is simply a bug. We should fix it to work with the debugger, and programs that advise or instrument code should have a documented way to arrange for 'called-interactively-p' to keep working. > I would like to make a suggestion. All these problems can be resolved by > introducing a special (dynamically bound) variable. Each call -- not only > interactive -- to an interactive function would rebind it to the value > providing all the necessary information about interactiveness of this call. This could work, but it would use the specpdl in an inefficient way, making many bindings that will never be used. There is also a speed issue: every function call would need to check whether the called function has an interactive spec. But maybe it won't be very bad. Here's another approach: give 'interactive' a way to specify a variable to bind for this purpose. That way, the variable would be bound only in functions that want it, and it would not interfere with the function's calling interface. The variable could be written as the second argument of 'interactive'. If we want to preserve the principle that 'interactive' has no effect on actual execution of a call to the function, we could make a new name so that (was-interactive foo) in the function body binds foo to a suitable value for the rest of the function body. To get the right results when advising or instrumenting code, we could define (advised-interactive foo) as an alternative to use in wrappers. (defun foo (y) (interactive) (was-interactive in-foo) ...) (lambda (x) (advised-interactive in-foo) (message "I am at foo") (foo x)) When the lambda gets called, 'advised-interactive' will bind 'in-foo' to say whether the call was interactive, and it will suppress the 'was-interactive' form in 'foo' from binding 'in-foo' (because they bind the same variable). We could also write them as (was-interactive (VAR) BODY...) (advised-interactive (VAR) BODY...) This is cleaner in that the scope of VAR is shown explicitly, but people would be surprised that these don't work when nested inside any other construct. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html.