The answer to all these things should be "just doesn't work in practise", not for real programs anyways. Unlike Lisp, Python doesn't lean itself well to this mode of development.
Primitive CLI-like tinkering, figuring out language features, calc-like usage - maybe. But not a single time in 15 years of doing Python across the industry I saw anybody using these features for serious program development, or live coding, or REPL-driven development.
>Primitive CLI-like tinkering, figuring out language features, calc-like usage - maybe. But not a single time in 15 years of doing Python across the industry I saw anybody using these features for serious program development, or live coding, or REPL-driven development.
I swear you people are like ostriches in the sand over this - Django, pytest, fastapi, pytorch, Jax, all use these features and more. I work on DL compilers and I use those features every day - python is a fantastic edsl host for whatever IR you can dream of. So just because you're in some sector/area/job that doesn't put you in contact with this kind of python dev doesn't mean it's not happening, doesn't mean that python doesn't support it, doesn't mean it's an accidentally supported API (as if such a thing could even be possible).
Really what this convo is doing is underscoring for me how there really is nothing more to be learned from lisp - I had a lingering doubt that I'd missed some aspect but you guys are all repeating the same thing over and over. So thanks!
> Really what this convo is doing is underscoring for me how there really is nothing more to be learned from lisp - I had a lingering doubt that I'd missed some aspect but you guys are all repeating the same thing over and over.
No, you keep on misunderstanding what people are trying to tell you. It’s a communication failure. The thing that you think you are doing in Python is not the thing that people are doing in Lisp.
As an example, I suppose that when you’re developing code in Python’s pseudo-REPL you often reimport a file containing class definitions. When you do that, what happens to all the old objects with the old class definition? Nothing, they still belong to the old class.
If you did this on a REPL connected to a server, what would happen to the classes of objects currently being computed on? Nothing, they would still belong to the old class.
In Lisp, it’s different. There is a defined protocol for what happens when a class is redefined. Every single object belonging to the old class gets updated to the new class. You can define code to get called when this happens (say, you added a new mandatory field, or need to calculate a new field based on old ones — and of course ‘calculate’ could also mean ‘open a network connection, dial out to a database and look up the answer’ or even ‘print the old object and offer the system operator a list of options for how to proceed’). And everything that is currently in-flight gets updated, in a regular and easy-to-understand way.
People are telling you ‘with Lisp central air conditioning, I can easily heat my house in the winter’ and you are saying ‘with Python, I can easily build a fire whenever my house gets cold too!’
As others here, I don't understand how those features (seamless continuation of a program with the exact state) could possibly work in Python.
What I do know is that the Python community has a propensity for claiming that approximations of complex features by gigantic hacks work and are sound, while they are not.
The Python community also has an extreme tolerance for unsound and buggy software that is propped up by censoring those who complain. Occasional complaints are offset by happy (and selected) marketing talks at your nearest PyCon.
I think in just about every response you left in these threads, you misunderstood what was being said. Possibly through impatience, or just plain arrogance. I really encourage you to spend some time trying to understand how interactivity/restartability (as in Lisp restarts, not process restarts) is built into the language. Especially if you're specializing in the compilers of dynamic languages.
You might also check out Smalltalk, which has a similar level of dynamism.
Listen, I've been on many sides: Lisp stuff, Python stuff, C stuff, etc. I don't think that "something has to be learned". Lisp has many good ideas, Python has good ideas. But REPL-driven development is not one of them. But let me explain.
You see, it's not about how REPL in Python just does not allow something (even though it is rather primitive). Python makes it superhard to tweak things, even if you can change a certain variable in memory. Here's why.
Think about Lisp programs, including OOP flavours. These fundamentally consist of 2 things: a list of functions + a list a variables. If you replace a function or a variable then every call will go through it. And that's it. You change a function - all calls to it will be routed through the new implementation. Because of REPL-centric culture of things people really do organise their programs around this style of development.
Python was developed with an dynamic OOP idea in mind where everything is an object, everything is a reference. Endless references to references of references to references. It's a massive graph, including methods and functions and objects and classes and metaclasses. There is no single list of functions where you can just replace this name-to-implementation mapping.
TL;DR Replacing a single reference doesn't change much in the general case. It does work in some cases. But that's not enough for people to rely on it as main development driver.
Python fundamentally makes a different tradeoff than your average lisp.
I've mentioned this in a sibling thread, but it's interesting to compare this to Ruby. Ruby does support the sort of redefinition you're talking about. And yet REPL-centric development isn't primary there, either. Yes, there are very good REPL implementations, but I don't know of anyone who develops at the Ruby REPL the same way you would in a Lisp REPL. Maybe it's a performance thing? Maybe it's the lack of images?
BTW, you mentioned that classes can be redefined in Ruby.
How does this work for existing class instances? Anonymous pieces of code, methods, etc? Even lisp itself does not save from all the corner cases, it's the dev culture that makes all these wonderful things possible.
The first time you do `class A....end` you're defining the class. Instances when they are created keep a reference to that class - which itself is just another object, an instance of the class `Class` which just so happens to be assigned to the constant `A`. If you later say `class A... end` and redefine a method, or add something new, what you're actually doing is reopening the same class object to add or change its contents, so the reference to that class doesn't change and all the instances will get the new behaviour. If you redefine a method, calls to that method name will go to the new implementation.
So in that sense it works like you'd expect, I think. As I said, Ruby is very lispy - Matz lists Lisp as one of the inspirations, and I think I'm right in saying he even cribbed some implementation details from elisp early on.
It just shows that there's no understanding of the depth of the problem.
Years ago I tried doing something like this (redefining functions, classes, etc) in a dev environment of a MMO game. This would be crazily useful as the env took 5-10 mins to boot. And game logic really needs tweaking A LOT.
I really wanted this to work. After all, it really feels as if python has everything for it. Banged my head against the wall for weeks, failed ultimately and gave up on live development in python completely.
In contrast, as a heavy emacs user, I tweak my environment a couple of time a day. I restart this lisp machine a couple of time a month.
No, you're fine. For certain things Python REPL-like live development is ok indeed. Say, if your program boils down to a list of functions. Think request handlers or something.
Primitive CLI-like tinkering, figuring out language features, calc-like usage - maybe. But not a single time in 15 years of doing Python across the industry I saw anybody using these features for serious program development, or live coding, or REPL-driven development.