I have a concern about REPL driven development, which is around how maintainable the result is. The reason people like REPLs is because they can experiment to discover the right way to write the code in a very fast feedback loop. This alleviates a huge pain when you are operating with uncertainties or at the edge of your knowledge - 'does this function return null if no matching entries or an empty list?' - etc. The…
On Repl-Driven Programming
151–160 of 210 posts
Re: On Repl-Driven Programming
#152Is there a modern non-Smalltalk, non-Lisp (or its derivatives) non functional imperative programming language that supports a "real repl" that the author is talking about? I don't know if that kind of environment is for me but I'd love to give it a spin. I have never found the REPL (the Python/Ruby REPL which is not a "real repl" according to this article) to be that useful beyond quickly playing with API of a librar…
Re: On Repl-Driven Programming
#153What a surprise, the functional folks are arguing that "Because your language is different than mine, therefore it's not as good as mine." I've heard people say that Java or C++ isn't a language, because it doesn't have features x-y-z when Racket does. Garbage. Similarly, this guy is saying that because Python's shell doesn't have breakloops, it isn't a real REPL. Also garbage. 99.9% of the time when using REPLs/shel…
I am not saying that your language or your way of working is not as good as mine. I'm not saying that you or anyone else should discard your ways of working and adopt mine.
I'm not saying that Python's repl isn't actually a repl. I'm not saying that everything needs to have breakloops. I'm not saying that I or anything I like is any holier than anyone else.
What I'm saying is I like a specific style of programming and it makes me happy. I think more people should know about it because it will make some of them happy, too. I would like that.
Besides just liking to make people happy because that's the kind of personality I have, I would also like it if demand for tools that support my preferred way of working increased, so that there are more of them available over time rather than fewer.
And, finally, I like to use the phrase "repl-driven programming" for the style I like because some time ago someone asked about what distinguished old-fashioned Lisp and Smalltalk environments from others that the questioner was more familiar with, and "repl-driven programming" was a phrase that person used. So I adopted the terminology. I think it's a reasonably good piece of jargon for its purpose.
We can sensibly distinguish a repl-driven environment--that is, an environment whose design is driven by the requirements of interactive programming with a read-eval-print loop--from an environment that merely has a repl as one of its affordances.
If the distinction isn't meaningful to you, then presumably "repl-driven" design isn't either, and you're presumably not one of the people I'm talking to.
Re: On Repl-Driven Programming
#154I have a concern about REPL driven development, which is around how maintainable the result is. The reason people like REPLs is because they can experiment to discover the right way to write the code in a very fast feedback loop. This alleviates a huge pain when you are operating with uncertainties or at the edge of your knowledge - 'does this function return null if no matching entries or an empty list?' - etc. The…
Code developed in a REPL would ideally be "pure", meaning it takes a value and returns a value without side-effects. Then others can experiment with it to their hearts content. Maybe it's ok to read from a database, but don't write. If you write to the database nobody else will dare touch your code.
For me, the whole point of the repl is that I want to build something incrementally, interactively, building it a little at a time by making small changes to it. I want it in memory, running and responding to my changes as I make them. Put this here; put that there. Change that around. Let me look at it; nope. Put that back where it was. Now add this.
If the repl is stateless then the whole purpose is defeated.
Re: On Repl-Driven Programming
#155Earlier quoted context omitted.
Code developed in a REPL would ideally be "pure", meaning it takes a value and returns a value without side-effects. Then others can experiment with it to their hearts content. Maybe it's ok to read from a database, but don't write. If you write to the database nobody else will dare touch your code.
That rule absolutely does not work for me. For me, the whole point of the repl is that I want to build something incrementally, interactively, building it a little at a time by making small changes to it. I want it in memory, running and responding to my changes as I make them. Put this here; put that there. Change that around. Let me look at it; nope. Put that back where it was. Now add this. If the repl is stateles…
Re: On Repl-Driven Programming
#156Earlier quoted context omitted.
That rule absolutely does not work for me. For me, the whole point of the repl is that I want to build something incrementally, interactively, building it a little at a time by making small changes to it. I want it in memory, running and responding to my changes as I make them. Put this here; put that there. Change that around. Let me look at it; nope. Put that back where it was. Now add this. If the repl is stateles…
I don't mean the REPL is stateless, but the code developed using the REPL would ideally be stateless. Stateless code would be easier for others to experiment with in their own REPL, without "oh no, you broke production with your REPL!"
This is about the development phase more than the production phase. Do something like this (directly in the REPL or in a buffer as mikelevin has described doing elsewhere):
(defparamater *db* (connect-to-test-db))
(query-db *db* (make-query some-query-description))
;; see that it pulls out the desired record
(let ((record (query-db *db* (make-query sqd)))
(update-record record)
(write-to-db *db* record)) ;; update the entry
;; rerun the query above to see that things changed as expected
;; rewrite that let as a defun:
(defun make-update-to-some-record (sqd db)
(let ((record ...))
...))
;; test that it works
(make-update-to-some-record sqd *db*)
;; see that it does in fact do the same as the let above.
;; move that to a permanent source file, and build it
;; into the system.
;; move tests into test file.
;; repeat with next feature/task
The functions run in the REPL are stateful, but we aren't careless about what they're touching.NB: You can connect to production environments. You can even connect to live, production lisp images. This could be useful for: profiling real-world activity, debugging real-world problems, applying hot-fixes. But especially that last one should be done carefully, and ought to have been validated using a test environment first.
Re: On Repl-Driven Programming
#157Earlier quoted context omitted.
I'm personally of the opinion that this isn't the same thing and I'm saying this as someone who wants to do this in python. Unless you've figured it out? In which case please say, because I want to code python like this. Specifically I write code in my editor, hit a keystroke and all the code at the cursor gets sent to my running python and evaluated. The editor needs to be aware of python's indenting rules so it can…
> Specifically I write code in my editor, hit a keystroke and all the code at the cursor gets sent to my running python and evaluated. The editor needs to be aware of python's indenting rules so it can do this, but once again if you've worked out a nice way to do this please say. Minimal keystrokes required would be great =)... ...I call this "copy/paste". And since I use X clipboard and a tiled window manager, it's…
There's a reason I'm specifying specific actions, I can easily see increasing the cognitive burden breaking the ease of that workflow. You can't tell me that putting your cursor to a code block and hitting a key is the same as selection, copy, swap to console, paste...
I've certainly had situations where I've done what you're describing and then still taken the extra time to setup the workflow I've described above because it's worthwhile when you're trying to debug a knotty problem.
Re: On Repl-Driven Programming
#158Earlier quoted context omitted.
I have worked on massive LISP projects that were developed using REPL-driven development, and your fears are critically valid. Even worse, this basically hamstrings it as a standalone application. The workflow to _use_ the application becomes "start the REPL under emacs and launch it", which is, in my personal opinion, a completely unacceptable distribution model. And if you don't use emacs, good luck to you! Once se…
Your observations are valid, and need to be kept in mind when developing in an exploratory, interactive way. Your alarm seems a little overblown. Maybe it reflects a particular bad experience? I've delivered a bunch of products built in the way I prefer to work, and it's been a long time since I've had the problems you're describing. Maybe that's because I ran into such such problems early in my career and learned wa…
Re: On Repl-Driven Programming
#159Earlier quoted context omitted.
That rule absolutely does not work for me. For me, the whole point of the repl is that I want to build something incrementally, interactively, building it a little at a time by making small changes to it. I want it in memory, running and responding to my changes as I make them. Put this here; put that there. Change that around. Let me look at it; nope. Put that back where it was. Now add this. If the repl is stateles…
I don't mean the REPL is stateless, but the code developed using the REPL would ideally be stateless. Stateless code would be easier for others to experiment with in their own REPL, without "oh no, you broke production with your REPL!"
As you're rummaging around through the dynamic state of the running system, you'll discover changes that need to be made, and you might discover them absolutely anywhere. Sure, you could always kill the running system, make the change to the sources, and rebuild the system, but that's exactly what we're trying to avoid.
Consequently, old Lisp and Smalltalk systems are allergic to restrictions on runtime changes. Loosely speaking, if I find something I can't change while my program is running, that restriction is a bug in my development environment.
Old systems like this will discourage certain kinds of changes because they're usually ill-advised, but will not forbid them, because forbidding them is anathema.
As an example, several Common Lisps implement package locks on certain system packages. A package lock prevents you from changing the definitions of system-defined constructs.
But it's Lisp, so it doesn't really prevent the change. It just makes it more inconvenient. You have to say "Mother, may I?" first, which gives you the opportunity to soberly consider whether making that specific change is really really what you want to do.
Re: On Repl-Driven Programming
#160This article helps us understand what real repls enable that interactive language shells do not. What would be very helpful next would be a video comparison of writing a program that is just complex enough to not be trivial or too artificial, first using the common approach, and next using repl-driven approach.
Why not just learn a Lisp yourself? You'll get far more out of it than watching a video. The old adage is still true: learning a Lisp makes you a better programmer. Your choices are: * Common Lisp: install emacs, SBCL and set up SLIME, * Clojure: install emacs, Clojure and set up CIDER, * Scheme: install emacs, racket (or guile) and set up Geiser, * Emacs Lisp: install emacs. You'll notice that they all involve emacs…