REPL Debugging approach in other languages?

I am asking myself in the context of my book Data-Oriented Programming whether Clojure REPL debugging approach is applicable in other programming languages where we constraint ourselves to immutable data.

Any thoughts on this topic?

1 Like

JavaScript, yes and no, You can have REPL in debugger being a dynamic language, but it’s debugger where you stop the world to use REPL. Otherwise you only got REPL at global scope since JavaScript modules are isolated, you cannot access via namespaces. And module importing can be awkward depending on whether it’s CommonJS or ES Modules, in Node.js or in browser, not so fancy as Clojure.

what do you mean by this? are you asking if immutable data is what allows that type of debugging? the answer to that is no. common lisp’s repl is more powerful than Clojure’s and it doesn’t have immutable data. the list of languages that force immutable data is pretty short and I’m not sure how many of them have equivalent REPLs. ocaml, for example, doesn’t tend to push the repl as much. I don’t see whether the data is immutable or not having any bearing on the repl.

I think it is because common lisp does not have immutable data that it needs a more powerful repl. With clojure, it is pretty easy just to pop in a (def v obj-map) any place in a function to get the value of variable as it was at that exact time in the execution. If obj-map was mutable, then you would never be able to access the value as it was at the time of execution. Hence why with common lisp you need to be able to stop execution and inspect the values as they are at a specific time.

So my opinion is that immutable data is critical for the type of repl “debugging” we do in Clojure.

it’s not hard to do clojure’s debugging with mutable data. copying a value for later is trivial in CL, so that’s not really a differentiator. you rarely need to do that, though, because of how much more control you have over the running image. you need to keep things around with Clojure because its error handling is comparatively crippled. but, again, whether the data is mutable or not has no bearing on that.

I’ll go ahead and say that I think Immutable Data does improve the REPL experience. Keeping track of state at the REPL can be challenging, it’s probably the biggest gotcha with it, and something you need to learn to manage to use the REPL effectively. Resetting state is super annoying. Having mostly pure code and centralized state in my opinion makes this a lot easier.

That said, I’ve not used Common Lisp, but I’ve coded extensively in Emacs Lisp and its REPL.

But on the other hand, mutability is also key to the REPL being a good experience, because you want things to replace themselves magically, so if you change B which is used by A, you want that to reflect immediately on A which is done by mutating the var A uses to refer to B to point to the new B, no need to reevaluate A as well for things to be reflected.

that’s true, but the state we’re talking about isn’t just the state of the data, but also the state of the code. if you change a record, a protocol, a function that’s being referenced by a variable, etc, you end up with both the old and new versions existing in the repl. CL doesn’t have that problem. if you redefine a record, it updates all the in-memory versions to match the new definition. immutable data actually requires more state resets. it’s simple to make a copy to save a starting point, so there’s no difference between mutable or immutable data with that.

it takes some getting used to, but the fact that exceptions aren’t fatal is really nice. if you call a function that doesn’t exist, it’ll throw an exception, which the repl catches. you can then define the function or tell it to call a different one, and it’ll keep going like nothing happened.

I’m not a huge repl user, but I use the CL repl far more than any other. the fact that code changes don’t require reloads makes it much nicer for exploratory coding. clojure’s repl I end up restarting all the time.

that’s true, but is a design decision. there’s nothing stopping you from writing your code that way with mutable data.