Skip to main content
added 738 characters in body
Source Link
Drew
  • 79.1k
  • 10
  • 123
  • 257

You don't need a macro for this. And you don't need (but you can certainly use) lexical binding.

;; Without lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after `(lambda (&rest _) (advice-remove ',symbol ',function)))
  (advice-add symbol where function props))

;; With lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after (lambda (&rest _) (advice-remove symbol function)))
  (advice-add symbol where function props))

(advise-once 'backward-word :before (lambda (_) (message "Eureka!")))

The reason you do not need lexical binding is that you are interested, when the function (lambda form) is used, only in the values of symbol and function, such as they were at the time the lambda-form list was created. You do not need variables symbol and function when the lambda form is used.

The use of the backquote syntax constructs a list that is a lambda form, where the values of symbol and function have been substituted in place of those variables.

Using lexical binding has the advantage that the lambda form can be compiled, because it is recognized by the compiler as a function, whereas in the case of using the backquote syntax all the compiler sees is code that constructs a list.

You don't need a macro for this. And you don't need (but can certainly use) lexical binding.

;; Without lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after `(lambda (&rest _) (advice-remove ',symbol ',function)))
  (advice-add symbol where function props))

;; With lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after (lambda (&rest _) (advice-remove symbol function)))
  (advice-add symbol where function props))

(advise-once 'backward-word :before (lambda (_) (message "Eureka!")))

You don't need a macro for this. And you don't need (but you can certainly use) lexical binding.

;; Without lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after `(lambda (&rest _) (advice-remove ',symbol ',function)))
  (advice-add symbol where function props))

;; With lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after (lambda (&rest _) (advice-remove symbol function)))
  (advice-add symbol where function props))

(advise-once 'backward-word :before (lambda (_) (message "Eureka!")))

The reason you do not need lexical binding is that you are interested, when the function (lambda form) is used, only in the values of symbol and function, such as they were at the time the lambda-form list was created. You do not need variables symbol and function when the lambda form is used.

The use of the backquote syntax constructs a list that is a lambda form, where the values of symbol and function have been substituted in place of those variables.

Using lexical binding has the advantage that the lambda form can be compiled, because it is recognized by the compiler as a function, whereas in the case of using the backquote syntax all the compiler sees is code that constructs a list.

Source Link
Drew
  • 79.1k
  • 10
  • 123
  • 257

You don't need a macro for this. And you don't need (but can certainly use) lexical binding.

;; Without lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after `(lambda (&rest _) (advice-remove ',symbol ',function)))
  (advice-add symbol where function props))

;; With lexical binding:
;;
(defun advise-once (symbol where function &optional props)
  (advice-add symbol :after (lambda (&rest _) (advice-remove symbol function)))
  (advice-add symbol where function props))

(advise-once 'backward-word :before (lambda (_) (message "Eureka!")))