Sunday, 12 October 2014

Hiding the REPL

I depend heavily on Clojure's REPL, because it's where I write music. Over time, however, I've become less focused on directly interacting with the REPL, and pushed it more and more into the background.

I use Vim Fireplace, which gives me the ability to evaluate forms in a buffer by sending them to an nREPL instance. There's also a REPL available within Fireplace, but I find I only use it for simple commands like stopping a piece of music or printing a data structure.

Speaking to Aidy Lewis on Twitter today, I've come to realise that there may be two different models for REPL-driven development.

Aidy described a model where the REPL is ever-present in a split-window. This brings the REPL to the foreground, and makes it conveniently available for experimentation. I would describe this as a side-by-side model.

On the other hand, I treat the buffer itself as my REPL. I write and refine forms, evaluating them as I go. If I want to experiment, I do so by writing code in my buffer and either evolving it or discarding it. My navigation and interaction are as they would be in any other Vim session, punctuated by occasional re-evaluation of something I've changed. This seems to me more like a layered model, with my buffer on the surface and the REPL below.

The reason I value this mode of interaction is it makes me feel more like I'm directly interacting with my code. When I make a change and re-evaluate the form, I have the sense that I'm somehow touching the code. I don't have a mental separation between my code-as-text and the state of my REPL session. Rather they're two ways of perceiving the same thing.

6 comments:

  1. I am a Lisp dilettante, but I believe my workflow to be set. I use the side-by-side model. Experimentation is done in the REPL and only when I am happy with the function, do I move it into the editor. I'd rather not have my editor polluted with things I may not use. I want the editor to inform me where I am at, my stable state. When I have moved a function into the editor, I will test it in the REPL. I may test the aggregation of functions in a written test or more often than not, the REPL.

    ReplyDelete
  2. Like you, I generally treat file buffers as REPLs. I mostly use the REPL-window-REPL (or whatever it's called) for playing around learning functions and APIs, but I often do that in file buffers instead.

    You may find the discussion at
    https://groups.google.com/d/msg/london-clojurians/7QBut2czNDg/8TQcFxFNl_YJ
    interesting.

    Simon

    ReplyDelete
  3. I followed your Twitter exchange and found it interesting. I definitely fall more on the hidden repl side of things, probably because of my vim-centricity. My user.clj file is usually hundreds of lines long with a history of experiments and other shortcuts I frequently use in a project. I only fall back to the (lein) repl for long-running operations, but that's mostly because of vim's pathetic blocking execution model. I tend to just write tests directly, often evaluating just sub-pieces of them until I've got them right.

    I used Emacs exclusively for about 3 months earlier this year and found remembering the current namespace and thinking about the repl window to be mostly a distraction. I also found vim's clear separation of verb (e.g. eval some code) and object (text object) to be much more powerful than Emacs' hodge-podge of evaluation function (happy to be proved wrong here). On the other hand, Emacs Lisp was a dream compared to vimscript and the execution environment was, of course, ridiculously superior.

    ReplyDelete
  4. I develop Cursive so this is very interesting to me - I definitely think there are two modes of work, and in fact I use both of them myself. When I'm experimenting with an API or an idea I often use the REPL editor, and when I'm writing tests for my code I generally ignore the REPL almost entirely - it's just there as an execution environment for my tests.

    I'm considering making Cursive show REPL results in popups when the REPL toolwindow is hidden to facilitate this style of work. Light Table is probably the best example of this style of working right now, where the REPL is always hidden and results are painted right on the work surface. Working like this in Fireplace, how are the results displayed to you?

    I'm also considering some functionality for semi-automatically creating tests from a REPL session, which I think could be really useful as a means of converting exploratory style programming into a more permanent test suite.

    Interesting comments about Vim's execution model too - I can definitely see how a verb/object command combination would be very powerful. Without that, I'm finding it difficult to find a balance between a combinatorial explosion of actions and forcing the user to execute two or three actions for common combinations - it's tricky.

    ReplyDelete
  5. In Fireplace, a results pane appears at the bottom of the window, only as big as it needs to be to display the result. Focus is in affected.

    ReplyDelete
  6. What is your opinion on LightTable and its ad hoc REPL? I found it extremely convenient to getting used to. I don't know about music creation, but LightTable evaluates everything the second you type it. Very cool stuff, and I am saying that coming from Eclipse and working a lot in Vim.

    ReplyDelete