GNU bug report logs - #61179
lambda inside interactive form of around advice isn't a closure

Previous Next

Package: emacs;

Reported by: Jonas Bernoulli <jonas <at> bernoul.li>

Date: Mon, 30 Jan 2023 15:49:01 UTC

Severity: normal

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Jonas Bernoulli <jonas <at> bernoul.li>
Subject: bug#61179: closed (Re: lambda inside interactive form of around
 advice isn't a closure)
Date: Wed, 08 Feb 2023 14:39:02 +0000
[Message part 1 (text/plain, inline)]
Your bug report

#61179: lambda inside interactive form of around advice isn't a closure

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to 61179 <at> debbugs.gnu.org.

-- 
61179: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=61179
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: 61179-done <at> debbugs.gnu.org
Subject: Re: lambda inside interactive form of around advice isn't a closure
Date: Wed, 08 Feb 2023 09:38:16 -0500
> Could you confirm that it works for you?
[ Confirmed.  ]

Thanks, closing,


        Stefan


[Message part 3 (message/rfc822, inline)]
From: Jonas Bernoulli <jonas <at> bernoul.li>
To: bug-gnu-emacs <at> gnu.org
Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: lambda inside interactive form of around advice isn't a closure
Date: Mon, 30 Jan 2023 16:48:13 +0100
A function used as an around advice may advise the advised function's
interactive form, using (interactive (lambda (spec) ...)).

Unfortunately this inner lambda expression is not turned into a closure
as demonstrated by this simple example:

  ;; -*- lexical-binding: t -*-
  (let ((var :value))
    (lambda (fn &rest args)
      (interactive
       (lambda (spec)
         (message "interactive: %s" var)
         (advice-eval-interactive-spec spec)))
      (message "body: %s" var)
      (apply fn args)))

Or if you want to observe the failure when trying to use such an advice:

  (defun -make-advice ()
    (let ((var :value))
      (lambda (fn &rest args)
        (interactive
         (lambda (spec)
           (message "interactive: %s" var)
           (advice-eval-interactive-spec spec)))
        (message "body: %s" var)
        (apply fn args))))

  (defun -command (arg)
    (interactive (list (read-string ": "))))
  (advice-add '-command :around (-make-advice) '((name . "-advice")))

Could this be changed in the next Emacs release?  Even if this should
make it into 29.1 (which I doubt), it would still be very useful for me
if this could somehow be rewritten to also work in older Emacs releases.
I have tried throwing an eval or two in there, but with limited success.

This gives me an inner closure, but the outside closure does not capture
the same environment it seems:

  (let ((var :value))
    (eval `(lambda (fn &rest args)
             (interactive
              ,(lambda (spec)
                 (message "interactive: %s" var)
                 (advice-eval-interactive-spec spec)))
             (message "body: %s" var)
             (apply fn args))
          t))

I got desperate and also tried things like:

  (call-interactively
   (let ((lex '((var . :value))))
     (eval `(lambda ()
              (interactive
               ,(eval '(lambda (spec)
                        (message "interactive: %s" var)
                        nil)
                      lex))
              (message "body: %s" var))
           lex)))

Thanks for your help!
Jonas



This bug report was last modified 2 years and 159 days ago.

Previous Next


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