Fork me on GitHub
#off-topic
<
2022-02-28
>
Ethan Miller02:02:22

Wasn't sure where to put this question... I'm trying to find a very concrete way to explain why the Clojure REPL is good to people at work. I've come across some articles about this that have been helpful in a high-level way, but I'm trying to find a very concrete way to show why the REPL works better in Clojure as a result of the characteristics of the language. Like is it possible to demonstrate, say with a Python REPL, why it doesn't work as well as a result of something about the language that contrasts with Clojure. Or: is the answer more that the tooling (i.e. Cider, Calva, etc...) is just superior and it's not something specific about the language that makes the Clojure REPL experience good?

Ethan Miller02:02:55

This is the one article I've looked at that seems to go into most detail question, specifically the section "What makes a programming language REPL-friendly?"

kenj02:02:09

At some point of toyed with trying to do REPL driven dev in Python to see what it was like. PyCharm does have a shortcut for sending things to the REPL window. The biggest difference is that in Clojure, everything is an expression, which means you send any part of your code. Not so with Pythons mix of statements and meaningful white space along side expressions. The other part is the tooling. Sure PyCharm had a shortcut, but compared to what Calva offers in terms of sending various forms, it was night and day.

2
p-himik02:02:09

There's a good demonstration by Sean Corfield on the topic - should be easy to find on YT.

Cora (she/her)03:02:03

The value, for me, is in incrementally executing code as I write it. Each step along the way I can try things and confirm things are working the way I want. I get the feedback directly in my editor, making the feedback cycle incredibly tight and as fine or coarse grained as I'd like it. That instant feedback is so incredibly valuable. Many other languages try to give you the same thing in different ways: hot reloading, incremental compilation, automatically running tests, etc. These tactics all have positives and negatives but they're all trying to give you a faster feedback cycle. I think Clojure as a language is expecially well-suited to using a REPL to drive development. Specifically, being a functional language that uses immutable data structures lends itself to testing things incrementally and in isolation. Functions typically have all the state they need in order to execute passed in on each call, and functions generally can't change that state because of immutable data structures. This means there's no (or very little) state setup/teardown/reset for each execution of the code you're building.

Cora (she/her)03:02:44

but to see it you need to follow along with someone else doing development using a REPL, like @U2FRKM4TW pointed you to

Cora (she/her)03:02:11

I didn't fully get it until I paired with someone tbh

lilactown04:02:56

the ability to change a running program is the key detail

3
lilactown04:02:34

python and JS have REPL, but due the way their module systems and bindings work you can't patch a running program

lilactown04:02:12

a better way of describing REPL driven development is to relate it to hot module reloading

lilactown04:02:20

it's basically first class support in the language for hot module reloading. and can be done at a fine grained level - you can reload individual functions and vars inside of modules without touching the rest of the module

lilactown04:02:42

JS does this with a metric ton of awful tooling. same with other langs

lilactown04:02:02

clojure you just need a socket connection and an editor that can talk to it

Ethan Miller04:02:38

Thank you everyone. These comments are helpful. I think what I may be driving at trying to understand, just to put a finer point on it, is whether there is a characteristic of the language itself that makes Clojure’s REPL great / better. In other words, is it just an accident or a cultural predilection of the community that has led us to have things like CIDER for emacs that allow us to work in the editor. (In other words, is Clojure’s REPL experience better simply because nooone has bothered to build similar tools for other languages?) From the responses here, I think perhaps the notion that “everything is an expression” as well as the the idea that you can “change a running program” are key and seem to be related to the characteristics of the language as opposed to the existence of tooling that makes this possible. I’m trying to wrap my head around the “everything is an expression” idea first because it seems more basic. I wonder how one could illustrate this simply, perhaps making a comparison some other language. @UBHTL6AF3 you mentioned, e.g., that Python has a mix of “statements and meaningful white space.” Is it possible to given an example of what you mean?

Ben Sless05:02:11

By way of analogy, do you restart your machine every time you want to run a new script on it or install a new program? No, the computer is dynamically linked and alive and you can develop on it from within it.

👍 2
pez07:02:20

There's a, maybe subtle, difference between LISP REPLs and REPLs of other language paradigms in that with LISPs the REPL is an integral part of the language design. It is how programs are read and made to exist. With Python and JavaScript it is a separate tool. This has implications on the support that CIDER et al can provide on top of the REPL. They reach into the application being developed in a way that JS and Python IDEs just can't do.

pez07:02:56

Anyway, as has been noted in this thread before. The feedback loop is amazingly tight in Clojure, key contributors: • the running program can be modified • everything is an expression • immutable data • powerful data structures with literal syntax I think a language like SmallTalk is even more dynamic than Cloure, so it ticks the first box there. However, everything is not an expression making it a bit awkward to select the piece of code to send in ti the system. And data immutability is not a key language concept, making the evaluation of something having more side effects than it has in Clojure.

💯 1
pez07:02:27

I'll plug some videos where I try to make the case for Interactive Programming. • Solving FizzBuzz with the CLojure REPL: https://www.youtube.com/watch?v=U-cys75qaCw (short, w/o narration) • FizzBuzz again: https://www.youtube.com/watch?v=d0K1oaFGvuQ (longer, narrated) • Developing a mobile app as it is running: https://www.youtube.com/watch?v=5ZyAhGv55V0&amp;t=1559s The mobile app example makes it more obvious than the FizzBuzz videos, that the program is actually bing modified as it is running.

teodorlu07:02:33

https://clojurians.slack.com/archives/C03RZGPG3/p1646022878947789?thread_ts=1646014042.105639&amp;cid=C03RZGPG3 @U3RGL6XNF hi :) In addition to expression orientation I'd add plain, serializable data with literals. Just being able to type values in without "constructing them" is of great help. Usually, we can just paste values back in and they are still "right". Edit: just as @U0ETXRFEW noted!

olaf10:02:50

Just a good essay about using Lisp, but Paul Graham describes how the ability to live changing the code in production using the REPL was helping him to fix bug while at the phone with customers. http://www.paulgraham.com/avg.html

👍 2
lilactown13:02:28

@U3X7174KS yes, vars and the namespace system is what I was referring to

👍 1
lilactown13:02:09

this video I think is very relevant https://www.youtube.com/watch?v=3HxVMGaiZbc

👍 2
teodorlu13:02:00

While I agree, some of this is possible to achieve in Python using importlib.reload (redefine module without restarting process) and by catching NameError (hacky defonce for Python). I've written a tool for developing Python without restarting the interpreter: https://github.com/teodorlu/hotload It has a real advantage if you're using libraries that take a long time to start up, or if you're working with a system that has an embedded Python scripting layer and you don't want to loose context (such as https://en.wikipedia.org/wiki/Abaqus). File watcher + process restarts is a lot simpler, though. And the rest of the ecosystem doesn't really use in-process reloads.

respatialized14:02:09

https://nextjournal.com/mk/rich-hickey-on-repls I think Rich Hickey's comments on REPLs also offer some insight here - chiefly that the extensibility of Lisp readers, combined with the ability to read forms as data, make all Lisp-based REPLs more capable than the consoles of other languages. I really like the nested read example at the end, too.

👍 1
Benjamin17:02:41

I told a coworker once about a nightmare I had where I was putting a line of code between 2 csharp lines and then needed to start the program to try it out. I literally woke up with a "noo!"

clojure-spin 1
lsenjov04:03:34

Something that's not been mentioned in the thread so far, is that once you're in a REPL it feels much more like playing with code than actually working. Building something feels far more like playing with lego than grappling with a codebase. Other languages' workflow is "look at the types, look at the code, figure out what's going on, then make changes. Don't actually run the code, it won't give you much unless you're going into a debugger" With a REPL it's more "just run the code, look at what it's doing, move some things around to give yourself better understanding. Knock the tower over, build it up brick by brick till you see how it works."

clojure-spin 2
teodorlu09:03:53

And "feels like play" typically means you can focus on just exploring / learning. Not do arbitrary tedious work. Faster learning speed ➡️ faster iteration cycles ➡️ win!

teodorlu09:03:17

On a meta-note: I believe reflecting deeply on what the REPL is to be the key to understanding what's good with Clojure. It feels really hard to separate the REPL discussion from "how to use Clojure effectively".

pez09:03:25

I've read that Rich Hickey on REPLs before and didn't quite understand much. Read it again now, hoping things would have cleared up, but I still don't get it. It feels like I should, being a REPL tool smith and all.

teodorlu09:03:43

Yeah, I think the whole "I just use inf-clojure" might be the right attitude for Clojure / Common Lisp experts. But I would never have been able to learn Clojure without friendlier tools like Cider and Calva.

pez10:03:08

I posted a link to this post in the new #growth channel.

Benjamin17:02:53

today I learned that I just call "cider load buffer" on some data and then have it in *1 , previously I sometimes spit to a temp file and then read it

nice 3
Matej Šarlija19:02:28

there are a loooot of neat tricks like that

cider 1
vemv21:02:30

Is disabling third-party cookies altogether possible/practical these days? While still leaving JS enabled. (I use Chrome) I DNS-block loads of stuff by using popular lists but perhaps this is different. For a little context, I was particularly fed up of this widget

p-himik22:02:34

I encounter a website that simply can't work without third-party cookies once a year, if not less frequent. I have never seen such a widget - perhaps because I use uBlock Origin with a rather strict selection of rules.

🙏 1
jjttjj22:02:36

some of the "annoyances" lists included in ublock origin might block that

vemv22:02:37

could be. I've used annoyances in the past but IIRC it often broke sites e.g. modals would become uncloseable

vemv22:02:11

which is why I'm thinking of a "network-level" solution