6 ms·
The REPL is why I like python a lot as well, although it is not as powerful as lisp where you can inspect and modify running code easily, it really is a key fea
by dkasper 2y ago
The REPL is why I like python a lot as well, although it is not as powerful as lisp where you can inspect and modify running code easily, it really is a key feature for prototyping new ideas. More languages should have repls
- iLemming 2y agoPython (or any non-Lispy language) REPLs are not truly REPLs in the way that Lisp understands the REPL. Every phase of Read-Eval-Print-Loop cycle has limitations: Read: In Python, the input is read as strings of code, which are then parsed and compiled. In Lisp, the input is read as data structures (lists, symbols, etc.) due to its homoiconic nature (code is data). This allows for macros and syntax rules to be applied even before evaluation. Eval - The evaluation phase involves interpreting the compiled code. Python’s evaluation is less interactive; changes in function definitions or classes often require the code to be re-run entirely, and the state can become inconsistent without careful management. Evaluation in Lisp happens directly on the read data structures. Functions, macros, and variables can be redefined interactively without restarting the REPL, maintaining a more fluid development process. Print - The result of the evaluated Python code is printed out in a standard format. The printing is straightforward but lacks customization unless explicitly coded. In Lisp, results are printed in a way that preserves the structural representation of the data, facilitating easier inspection and manipulation in subsequent steps. Loop - In Python, the main loop doesn’t offer much in terms of tooling or integration. Extending the REPL with custom behaviors or tools requires additional packages or integrations. The Lisp loop often includes advanced features like hooking into debugging tools, live editing, and runtime modifications, providing a richer development experience. So, it really makes you ask: can you actually have a proper, "true" REPL in a non-Lisp language? So while it's fair to call them REPLs in a technical sense, they more like "interactive shells" and not REPLs. You really need a Lisp to have a proper REPL.
- edanm 2y agoI'm a very long time Python developer, but also did a project in Clojure, a type of lisp, over the last year. There is no comparison between the Clojure REPL and the Python REPL. Python's is just literally a shell that you connect to and can run commands in. The Clojure REPL is far closer to a Python Jupyter notebook (if you know about it) built into your editor - it's a long-running process to which you can send commands all the time. But because of the way lisp is structured, and because of the tooling, you can just write Python code in the file you would normally use, stand on one line, and hit a command to get it sent to the REPL and the output of it written in the editor. It's... hard to explain how powerful this is, and how much better things could be if we had similar tooling in Python. Note: I still much prefer Python for many reasons, but this one aspect is something that I also used to think (yeah, Python also has a REPL) and I realize now that I had no idea what power this really has in lisp-world.
- bcrosby95 2y agoI try to tell my friends this and they accuse me of "gatekeeping" REPLs and that I'm an old man yelling at the cloud.
- iLemming 2y agoIt's actually not that hard to explain, yet without experiencing it firsthand, it is hard to see what this REPL fuzz is about. So, let's take a minimal, simple example: if True: print("Hello, Python!") and the equivalent code in Clojure: (when true (println "Hello, Clojure!")) In Clojure, you can send any expression fragment like a single symbol, list or even incomplete code and it will be evaluated according to its context. So, you can sent `true`, you can send `println` and you can even send `(when true println)` or `(when true (println))`, or even `(when true ,,,, (println))` (you can replace commas with line breaks if you want) and it will still be evaluated. In Python, you can send `True`, and you can send `print`, but you can't send `if True: print` (even with corrected indentation), because Reader would have hard time making sense of that. In Python, you need to adhere strictly to its syntax, and partial expressions that don't form a complete statement won't be evaluated meaningfully. In contrast, Clojure's REPL can work seamlessly with code fragments because the underlying representation of code is just data structures that are always valid within the REPL context. What makes it mind-blowingly cool is that you can send these expressions to a remote REPL without any transformation, serialization, or encoding, because it's not just code — it is data. In fact, some teams do just that. They'll keep an open socket on a running app, possibly performing somewhere in the cloud, so they can interact with it in real time. Putting aside the notion that this might not be the greatest idea, let's agree that this is a cool feature. The famous example of that is when something broke on Deep Space 1 (DS1) spacecraft in 1998, the team was able to fix it via REPL, see https://www.youtube.com/watch?v=_gZK0tW8EhQ https://www.youtube.com/watch?v=_gZK0tW8EhQ - "The Remote Agent Experiment: Debugging Code from 60 Million Miles Away" Sure, yes, Python is great, but when it comes to REPL stuff, you simply need a Lisp. It really is an amazing feeling when you can, for example, poke into any HTML element on a page dynamically, directly from your editor. Sure, you can do that with devtools in the browser, but it's not the same. You still have to switch to the browser; you can't type statements that are too long; and it's just not very convenient. Very nice (now years old) example is when Bruce Hauman showcased developing a "flappy-bird" clone - he would tweak the params, or straight change the code in his editor and the bird in the browser would fly differently, it's literally like writing code while playing a video game. Or Sam Aaron, writing music with Overtone is another great example. Another, more practical example is when you're exploring API response results, if you have REPL - you can send a single request and then dig through the data - group it, slice it, dice it, sort it, etc., something seemingly simple like this would require a bit more effort with any other language. I have my editor connected to a Clojure REPL instance at all times; I never know when I might need it.