tl;dr
1. no part of the system off limits
2. pervasive interactivity
3. homoiconicity
tl;dr
1. no part of the system off limits
2. pervasive interactivity
3. homoiconicity
I'm trying to imagine using this style of programming in Python, but the type-redefinition problem is still there
But usually there is something around it. Typically a Lisp system can run several REPLs at the same time, one might be a break loop. You can define a function in another REPL and use it in the break-loop. You can define the function by loading code in a break-loop.
An interaction might be (here in LispWorks):
CL-USER 6 > (> (sin-x2 3) 0)
Error: Undefined operator SIN-X2 in form (SIN-X2 3).
1 (continue) Try invoking SIN-X2 again.
2 Return some values from the form (SIN-X2 3).
3 Try invoking something other than SIN-X2 with the same arguments.
4 Set the symbol-function of SIN-X2 to another function.
5 Set the macro-function of SIN-X2 to another function.
6 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 7 : 1 > (load "~/sin-x2.lisp")
; Loading text file /Users/foo/sin-x2.lisp
#P"/Users/foo/sin-x2.lisp"
CL-USER 8 : 1 > :c 1
T
A function SIN-X2 does not exist. There is an error and we get a break-loop. The break-loop is one level deep. All of Lisp is available in a break-loop: the compiler, the code loader, the evaluator, ... Lisp stays with the break-loop in the context of the error.I define/write the function in a file and the load the file. Loading the makes the function available in the running Lisp.
Then I use the continue restart to try to find the function again -> the error is gone
It's impossible to do with Python, or any other language that wasn't created with image-based runtime. I tried. This approach only works when the "vertical integration" reaches from the very bottom (compilation, stack handling, memory allocation, object creation) to the very top (editing the source, refactoring, test runners, etc.) It's incredibly powerful when it works and is done right. Imagine your whole OS being built around GDB, with extremely late binding of everything and each method being a separate .so/.dll. It would probably be incredibly slow, which is why Smalltalk and Smalltalkers pioneered JITs - but it would also allow you to override any part of your running system while it's running.
https://www.akitaonrails.com/2007/12/15/chatting-with-avi-br...
I’m not aware of a way to get code back out of the Lisp environment, but I’m fairly new to all this.