7

For example,

(defun create-function (number)
  `(lambda () (* ,number ,number)))

(defalias 'square-two (create-function 2) "adds two")

(square-two)

3 Answers 3

6

Edebug does not support instrumenting code constructed at runtime. If you try to instrument create-function, then the stepping will occur when you evaluate (create-function 2), not when you execute square-two.

Edebug does support instrumenting lambda forms though, so you can rewrite your example using lexical binding:

;;; -*- lexical-binding: t -*-
(defun get-lexical-function (number)
  (lambda () (* number number)))

(defalias 'square-two (get-lexical-function 2) "adds two")

Then if you instrument get-lexical-function before evaluating the defalias form, you can step through the lambda when evaluating square-two.

3
  • "Edebug does not support instrumenting code constructed at runtime." What does that mean? Are you not instrumented code constructed at runtime in your second example? Commented Feb 28, 2021 at 20:55
  • No, the code of the closure is already constructed, filling in the lexical binding doesn't make any new code.
    – npostavs
    Commented Mar 1, 2021 at 13:14
  • I don't understand. I think we are thinking of two different "runtimes" Commented Mar 3, 2021 at 5:46
2

Yes.

M-x debug-on-entry RET square-two RET

M-: (square-two) RET

Debugger entered--entering a function:
* square-two()
  eval((square-two) nil)
  eval-expression((square-two) nil nil 127)
  funcall-interactively(eval-expression (square-two) nil nil 127)
  call-interactively(eval-expression nil nil)
  command-execute(eval-expression)

Use d to step through the function. Use c to skip through a step (skip substeps). And as always, C-h m tells you more about the debugger, including other keys.

3
  • 2
    The question title mentioned edebug, not debug.
    – npostavs
    Commented Nov 26, 2017 at 19:46
  • @npostavs: Hopefully someone will post an answer specific to edebug. I don't use edebug, so I can't help there. If edebug cannot be used for such a use case (I tried briefly, but I didn't find a useful solution), an alternative is to use the standard debug. But I imagine that edebug can be used for this too.
    – Drew
    Commented Nov 27, 2017 at 1:43
  • Yes, I'm primarily interested in edebug. I've tried using edebug-on-entry to little success. Commented Nov 27, 2017 at 1:44
1

BTW, while npostavs's solution is the better option for your example, in those cases where you really do need to build the code manually with backquotes (e.g. inside defmacro), you can try:

(defun create-function (number)
  (edebug-\` (lambda () (* ,number ,number))))
2
  • Hmm, it's interesting, but I can't quite make it work. I get (invalid-function square-two). Changing to (defmacro create-function (number) (edebug-` (* ,number ,number))) produces working code, but I still can't manage to step through it.
    – npostavs
    Commented Nov 27, 2017 at 10:54
  • Hmm... I guess it's broken somehow, then. I know I've seen it working (back when I bumped into it some years ago while trying to fix something in Edebug), but I've never really made use of it.
    – Stefan
    Commented Nov 27, 2017 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.