I am not convinced that immutability matters; this seems like a bias. After all the original REPL, and the name itself, was in Lisp (note that the first Lisp implementations were <i>not</i> interactive, but it was the first interactive language) and Lisp doesn't have immutable data structures.<p>(READ, EVAL, and PRINT are all old Lisp primitives, and the REPL was literally implemented with them. There's also a complex macro called LOOP but it was added much later, and is not integral to the language)
Using Emacs' Elisp for a short while helped me unlearn some REPL antipatterns I acquired during Clojure development (some of them unfortunately presented in this article), especially this: instead of typing something in the REPL, executing it, then copying it back into your actual source file, you can just write it in your source file and use "evaluate current form" or "evaluate form before current point" to send it to the REPL process for evaluation instead of painstakingly entering it in the REPL and copying it back. Note that this is not a conventional hot-reload, but the form is sent as literal to the REPL (where indirectly, hot-reload may occur).
With fast compiling languages a unit test is not for off from being a REPL. In Java I use JUnit as a REPL.<p>Actually I prefer unit tests over a REPL the same reason I prefer bash scripts over one liners or SQL scripts instead of typing into the interpreter... I don't like the ephemeral nature of REPLs.<p>Also with true REPLs unlike the debug unit test approach I mention with Java you really need the language to be dynamic. I'm not entirely sure why but static type languages are not very good at allowing code modification while running (I mean I have ideas but I don't know precisely if there is an actual theoretical limitation).<p>I guess I prefer static analysis over the complete ability to modify the code base while running.<p>Only add my 2 cents because the article doesn't mention any negatives to REPLs.
"Finally, not all programs need be fully automated - sometimes the middle ground between manual and automated is exactly what you want. For instance, a REPL is a great environment to run ad hoc queries to your database, or perform ad hoc data analysis, while leveraging all of the automated code you have already written for your project"<p>This is exactly why I love Python. My Django webapp gets features (DB reports, external API pushes, etc) added as the client's budget allows, and before they are I'll often do them manually. Given that the UI for a new feature is usually the most work, it's been working well.<p>So the process usually goes: REPL/Django shell -> Django management command -> End-user facing feature. I'll grab what I did the first time in the Django shell, and put it into model logic plus a tentative management command. Then the next time I have to do the task I'll make sure the command works properly. And then when the budget allows I'll add access via the UI.<p>Ninja edit: I forgot to mention that `import ipdb; ipdb.set_trace()` is invaluable to get to the point in the HTTP response code where you can start adding new stuff or diagnose errors directly.
I loved this article. I am a huge proponent of development ergonomics, and clojure(script) are really fantastic in this area. Most languages have a pretty similar standard set of tooling, but the pieces that a language does exceptionally well really stand out in cases like this.<p>I'd really love to see what languages designed specifically with ergonomics/tooling in mind look like
Matlab has a nice sort-of-repl feature which I miss in every other language: you can separate the code in a file into several blocks and then execute the current block (the one with which contained the cursor) with ctrl+enter. With this feature you still have the full text editing capabilities but you also have a flexibility you get from a repl.
Take a look at Smalltalk's environment and take a look a t Common Lisp's REPL. They have all the features that make for a good 'REPL'.<p>(As noted before, REPL is a Lisp term that stands for:<p>read - from keyboard input, parse the input string into the syntactic structure of the language<p>eval - eval the expression, this includes binding variables or defining new functions, also re-defining functions, even if such function is currently under execution on the running program.<p>print - print the result of the evaluation (in Lisp all expressions evaluate to something, even if this 'something' is NIL).<p>loop - go to 'read')
> Data literals. That is, the values manipulated in the programs have a textual representation which is both readable for humans and executable as code.
--8<--<p>This is not a dig at Kotlin/Java/Whoever but it bugs me (coming from Ruby) no end when regexen don't get to have a regex literal syntax and a match operator. I was going through the Kotlin language docs last night and its such a concise language with well thought out syntax and this omission jumped out at me.<p>Is it me? Do others really not think it's a big deal? I learned how to code via BASIC then ASM then C and early C++ and none of these had regex literals so for the longest time I literally (hah) did not know what I was missing. Now I can't imagine why a language wouldn't have them. I guess Ruby shows its Perl heritage. But Javascript has 'em, <i>you go Javascript</i>, and thus Typescript. And don't get me started on raw strings """Yuck!""" dear Lord, how gruesome. I think how Perl6 is brace savvy is the way forward. I'd also like to be able to specify my own braces to construct my own type as a shorthand, that'd be great DSL, so that,<p><pre><code> i = %something%
</code></pre>
would construct an instance of type Foo assuming the correct %T% (by way of example) constructor syntax. That'd be neat-o.
I personally prefer to develop by writing small functions and pairing them with a small test. Hacking in a REPL environment, saving the result and calling it source code has not worked out well for me, I end up producing spaghetti :)<p>I do however find REPL to be invaluable when experimenting/doing research. When you don't even know what the end result is, or when exploring data, you need to iterate over many ideas as quickly as possible and REPL is the fastest way to do that.
Quokka adds a nice repl like experience for JavaScript/typescript to various editors. I'm a fan of their products!<p>Hydrogen is quite nice for python repl development in atom. Hydrogen connected to a remote kernel plus a script to synchronize files to a remote server replaces writing code in Jupyter notebooks for me (I just can't enjoy editing code in a browser ...)
I like the idea of <i>accessible</i> code. It seems the next level after testable code.<p>Code with a lot of mockable dependencies is usually considered testable but sometimes it's a pain to setup.<p>Accessible code seems to fix this. Instead of taking dependencies, return some data so it's easy to check what your component does in isolation.
There's a lot of excitement about compiled languages lately, and many seem to wonder if interpreted languages are dying. Unfortunately I don't see the value of a good REPL brought up in those conversations very often.
I think REPLs work better in languages that provide 1st class immutability support, since it's easier to set up state once, then play with functions without having to re-set up state every time you tinker.
Yes, Clojure(script)'s REPL experience is really amazing. I don't think there are any general-purpose languages (beside Common Lisp) actively being used today that even come close in comparison. What's comes with Python, Ruby, C#, JavaScript, etc. - is a feeble attempt of an interactive shell, those aren't really REPLs. Even with Haskell I was really surprised to find out that you can't "send" any selected piece of Haskell code onto GHCI.