Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

When you evaluate a form deep in a function, how do you handle variables that are defined "outside"? How can you evaluate such expressions?


Cider (the clojure plugin for emacs) has a variant that prompts you for the the values for those variables.


Which function is that? I couldn't find it in the docs


hmmm ... what if it's a closure, and it depends on a huge lexical environment?


Oh nice. That's one place where Clojure beats Common Lisp then..


Does it? Asking for a value when encountering an unbound variable is a default restart

    $ sbcl
    This is SBCL 2.1.1.52.HEAD.321-f8a57bcca, an         
    implementation of ANSI Common Lisp.
    More information about SBCL is available at 
    <http://www.sbcl.org/>.

    SBCL is free software, provided as is, with absolutely no warranty.
    It is mostly in the public domain; some portions are provided under
    BSD-style licenses.  See the CREDITS and COPYING files in the
    distribution for more information.
    \* (\* x x)

    debugger invoked on a UNBOUND-VARIABLE in thread
    #<THREAD "main thread" RUNNING {1001860103}>:
      The variable X is unbound.

    Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

    restarts (invokable by number or by possibly-abbreviated name):
      0: [CONTINUE   ] Retry using X.
      1: [USE-VALUE  ] Use specified value.
      2: [STORE-VALUE] Set specified value and use it.
      3: [ABORT      ] Exit debugger, returning to top level.

    (SB-INT:SIMPLE-EVAL-IN-LEXENV X #<NULL-LEXENV>)
0] 2

    Enter a form to be evaluated: 3
    9
    \*


Yeah, in fact, Clojure needs special tooling for this, while it’s built into CL’s execution model.


This is interesting tool[1] that allows much the same with Clojure

[1]: https://github.com/IGJoshua/farolero


Actually, yes I seem to remember it doing that a while ago. I think my Emacs setup has messed up somehow. Now I just get:

   Debugger entered--Lisp error: (void-variable k)
And then a stack trace. No option for restarts.

It works if I run from the command line though..


I suspect you are right. Rebinding an inner function inside another function that contains variables probably will not work. But you could still alter and rebind the entire thing. And that is still flexible; you can still change a running program on the fly with only that ability. And you can always reference objects at the top level.


Cursive has a repl powered debugger just put your breakpoint there use the repl to trigger the call then use intellji's debugger to step through

If you want to run expressions in context just use the expression editor like a normal repl

Something I haven't tried yet is redefining functions at debug time can't see why it wouldn't work though


Smalltalk famously let you code inside the debugger. You can run code with methods that don't exist yet and add them in the debugger when it notices they are missing.


You can use a REPL powered debugger. You can interact with the debugger to a higher degree than with most mainstream languages. It’s not quite as powerful as CL though, from what I’ve read.

Or you pull out expressions and test them in isolation with given (assumed) inputs.


You can essentially give values to global variables with same name as those outside variables.


By evaluating outer forms first.


The repl maintains an environment.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: