emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Brittleness of called-interactively-p


From: Richard Stallman
Subject: Re: Brittleness of called-interactively-p
Date: Sun, 12 Jul 2015 17:59:22 -0400

[[[ 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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]