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 seems to be a fundamental difference between "REPL"s and "REPL but more like a shell" that we continue to run into when discussing REPLs. If you take a look at the blogpost (or the video adamkl posted in this thread), you'll see that the REPL discussed works in a fundamentally different way than what Ruby and Elixir does.
I've read this argument several times in several places and I'm still unclear how this is substantively different than setting up whatever arbitrary state you want to work with in tests and dropping into the console from there. Super open to be enlightened, but up this point I haven't been persuaded.
Ok, so after RTFA I think the only thing described that I can't do in Elixir is seamlessly move state from the REPL to the code. The utility of that for me doesn't feel huge. Yes, I will copy and paste a line from the console to the test or the code, but (a) I don't think that's really slowing me down a ton and (b) it gives an opportunity to ensure that the thing I'm moving is exactly what I want.
Because you don't just drop into the reply in tests. You can drop into the repl on a production system. Or during a live dev env. No more guessing what the input was that blew things up, your gonna do that investigation on the real patient.
Yeah that's a bit primitive compared to what the guy in the video is demonstrating. He's sending arbitrary forms from source files as well as from a dedicated input area to a REPL, the forms are evaluated and the printer understands that either more Clojure forms being returned or more output.
What are peoples thoughts on separate input form area (like the lower right text input area in the video), versus e.g. in SLIME where the input prompt is the output buffer and moves with the last output? I always thought he former was more awkward, but maybe there are advantages...
Those are the same; partial input in your SLIME doesn't get overwritten by new REPL output. Same with pretty much all terminal emulators / shells. Input line is special.
- 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.
I like GHCi, but it's definitely missing some things if we're talking about using a REPL for development rather than just experimentation (which is a valuable thing itself).
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 :)
I used ipython for many years, but eventually moved on to jupyter. For me, it's even better. It still supports ? and ?? and the case of re-using your normal imports and variables is handled well by having a saved notebook.
I never needed repl because I used debug and continue in Visual Studio for C++ and C#. Its awesome - stop at a breakpoint then you can amend or insert any line of code, move the current line pointer up or down. Now I'm not on those platforms any more I use REPL, but I dont like it as much.
I find this article to be excellent description of what makes a great REPL and what makes REPL development powerful.
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)
If you can develop your whole application in your REPL without restarting your application that's a tell that you have a good REPL
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
29 comments
[ 2.8 ms ] story [ 73.1 ms ] threadAnd 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].
[0] https://nts.strzibny.name/elixir-interactive-shell-iex/
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 ;)
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.
[0] - https://vimeo.com/230220635
- :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 :)
also, it's super customizable -- i have a custom one that injects a bunch of imports and variables that i always use.
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)
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!