The description here of using the Clojure REPL for development is one of the best I've seen. I think part of the issue is nomenclature -- Read Eval Print Loop applies to lots of systems in lots of languages that many devs are familiar with that are not really what Clojure devs mean when they say "REPL." The actual experience is closer to something like Smalltalk where you alter a running system and experiment with it incrementally.
I guess I need to watch some of the videos he links, because this sounds horrible to me.
I mostly work in Python, which has a repl (though I'm sure not as complete) and sometimes I poke around in it. But if I am working on a real project, or even just a small script, I always want to run it from the beginning on every invocation, because anything short of that is not proof that it works.
"Editing a running system" sounds like a nightmare! How could you ever know things would actually work?!
> "Editing a running system" sounds like a nightmare! How could you ever know things would actually work?!
This is why Clojure developers love immutable data and pure functions so much. Say I am writing a web frontend for managing a list of users, and I want to implement some kind of filter and grouping flow on them for some business reason. Since I know the users are immutable, I know that when I am evaluating code in the browser to test out exactly what filter logic is correct I am not actually changing anything about the system.
I see REPL driven development more akin to writing music. I pick up the guitar and start playing. I can work on a small fragment and improve it until it sounds good to me. Or I can play the whole song. At all times I have instant feedback and I can hear what I'm working on.
In the case of the REPL you are playing your program. You can play a file, a function, or half of a function. Until it sounds right.
I lack the skill to use music notation for composition, so I rely on my instrument to give me feedback. And I lack the skill to execute the program in my head before I press compile, that's why I rely on the REPL.
Late to the conversation, but... I think unit vs integration testing is a good model for comparison. When I'm working in a REPL, I'm trying out individual functions to ensure that they provide the desired results (unit). Most functions are referentially transparent (if not totally pure), so this allows for fast/easy experimentation. If I want to test major code paths in a program, I can call "driver functions" or primary code paths to explore the results (integration). None of this is a substitute for real unit/integration testing, but it makes for some very rapid development. I worked in a lot of "REPL" (Python included) before I had the creme de la creme experience of using Clojure with Spacemacs and Cider. It's truly a different beast, and I'd withhold judgement until you've tried it (or something very comparable).
I do use REPL-driven development even for Python. (And why not? Like Norvig says, Python is basically lisp with traditional syntax.)
> How could you ever know things would actually work?!
Eventually you would run the project from beginning to end to make sure it works. REPL just allows you to by-pass that during development for rapid feedback. If the project takes 2-3 seconds to boot, we are talking about a difference of getting feedback in milliseconds vs several seconds - which makes a huge qualitative difference in developer workflow.
The point is precisely that you do NOT have to run it from beginning on every invocation. Doing it once in a while is enough.
I had similar preconceptions from Python's REPL. Now after reading (at the least the first section of) the article and watching the video my mind is blown.
I've also been dabbling with Emacs Lisp recently and it appears that you can do basically the same thing.