What makes a good REPL? (2017)
vvvvalvalval.github.io
vvvvalvalval.github.io
In languages like Clojure and many other older languages this is the default method of development, it's like being able to develop your backend web app, and whilst your web server is still running dynamically inject + install a new function to it at runtime
Then pass new values through it, consider the output maybe inject a refreshed version of the same function, rinse and repeat until your app is done
Most developers are like "lol I can call my function in my REPL" and it's completely not the same thing, a good REPL is crack
Developing your app from inside your running app is next level that requires editor tooling + correct workflow + language support
You need an editor that shows the results of REPL commands either inline or in a REPL window, you need a language that allows rebinding of symbols and functions at runtime, you need a editor that lets you send forms from files into the REPL buffer, you want an expression based language to make the sending forms easier
A workflow like rich comments (https://betweentwoparens.com/rich-comment-blocks) is recommended so you're not micromanaging your REPL forms, and editor shortcuts to make this is as quick and natural as possible
So, basically, Smalltalk!
Coding in Clojure with Emacs CIDER - with it's integrated code editor and REPL - is the most fun I've ever had with programming. The immediate feedback, the incremental building up of functionality, the ability to interactively evaluate nested expressions at any depth - it all feels very fluid and natural and immediate once you learn a few keyboard shortcuts.
Seriously, it was what finally got my programming mojo back after going stale from decades of C++ & Java. In my search for "something better" I also had good experiences with Ruby, Python, and Groovy and I also used their REPLs occasionally, but those REPLs never became central to the coding experience as it is with Clojure. (maybe I was missing out)
I watched it for the first time a few months ago, and its what really got the idea of REPL driven development to "click" in my head.
Being able to interactively build functionality from the ground up was an eye-opener.
- :type and :info
- :doc
- Debugger + breakpoints
- :print :sprint for understanding laziness
- Can run shell commands with :!
- Can set different compilation flags for the loaded code vs the repl session.
- Can define your own repl commands
I use ghci for developing standalone modules, running HTTP servers, and running unit tests.
The biggest thing I wish it had was something like chez scheme's `trace`, which causes it to print out a function with its arguments every time it is called.
The two biggest things, I think, are:
1) GHCi allows rebinding symbols, which is great, but it doesn't have good mechanisms for propagating that change. Haskell being Haskell, I don't really expect change local binding to propagate to everywhere that binding has been used. But it would be great if I could point at an identifier I've declared and say "redefine everything that was used to get here".
2) The path from REPL to source code in a file is very manual. I often find myself copying code out of my history, and have to manually remove bindings that I've shadowed since.
The tooling that it does provide, though, is really great :)
And I have to say that the Elixir one is pretty slick. If you happen to try Elixir or you are curious what its REPL can do, I wrote "8 + 1 things to get you started with the Elixir's interactive shell"[0].
There is some more discussion around this whole REPL vs shell thing here too: https://twitter.com/VictorBjelkholm/status/12660699623613726...
Edit: Funnily I just discovered your blogpost is titled "interactive shell" but your comment talks about REPL ;)
also, it's super customizable -- i have a custom one that injects a bunch of imports and variables that i always use.