←back to thread

89 points Numerlor | 1 comments | | HN request time: 0.211s | source
Show context
behnamoh ◴[] No.41851517[source]
I want a Lisp-like REPL for my Python programs that is available to the user who runs my compiled Python program (so, I want compilation as well). The user will be able to interact with my program (instead of just running the main function), change function definitions, etc. and mold the program to their specific use case while it's running.
replies(5): >>41851780 #>>41852247 #>>41852604 #>>41853249 #>>41853727 #
ks2048 ◴[] No.41851780[source]
Some things are a bit awkward, but what specifically can't you really do in a Python REPL? You can dynamically overwrite functions in an imported module, you can re-import modules with importlib, etc. I ask because my Lisp experience is limited.
replies(1): >>41851857 #
behnamoh ◴[] No.41851857[source]
Lisp REPL keeps the state of the program because it is a live image. With Python REPL you need to rerun the program to set the variables to their values.
replies(1): >>41852345 #
ks2048 ◴[] No.41852345[source]
You can create a file, example.py:

    import time
    value = "foo"
    def go():
      for i in range(10):
        print("...", i, value)
        time.sleep(3)
Then, in repl,

    import example
    import threading
    thread = threading.Thread(target=example.go)
    thread.start()
It will slowly print out messages and you can do "example.value = 'bar'" in the REPL and it will change.
replies(3): >>41852396 #>>41853872 #>>41854578 #
behnamoh ◴[] No.41852396[source]
it's not the same though—In Lisp, when you compile your program, a Lisp run-time is attached to it so you can either run the program normally (like any binary) or you could REPL into the program and see what the values of variables are (these values were set at compile time). This is helpful when you have a large dataset you don't want to load over and over.
replies(2): >>41853928 #>>41854101 #
d0mine ◴[] No.41854101[source]
Repl can be attached to a live python process (you don't need to restart anything)

https://stackoverflow.com/questions/1395913/how-to-drop-into...

You could do it even without cooperation from the python app using approach similar to pyrasite (though it is much easier with cooperation--just add a couple of lines).

replies(1): >>41854937 #
behnamoh ◴[] No.41854937[source]
That only works where you specified (e.g., line 42 where you invoke `code.interact(local=locals()`). Lisp's approach works anywhere (anytime an exception is raised you're thrown in the REPL).
replies(1): >>41856211 #
1. d0mine ◴[] No.41856211[source]
gc allows to get any [non-leaky] object from anywhere. You can even drop into repl over the network.

Debugger can be started on exception if desired e.g., pytest provides `--pdb` arg. Though repl is different--you don't need to interrupt the app itself while you are inspecting it e.g., async repl can be run in the same thread alongside the rest of the app.

I can't remember a single case there Python's dynamism weren't enough for the task (most of the times it is the opposite--there could be less dynamism).