9 ms·
Python is dynamic and other than restartable exceptions I think it offers all of the features you mention. Indeed it's fairly common in the Python world to take
by laurencerowe 4y ago
Python is dynamic and other than restartable exceptions I think it offers all of the features you mention. Indeed it's fairly common in the Python world to take advantage of that dynamic nature by distributing application security patches as 'monkey patches' [1] as code which runs to dynamically update other code.
[1] https://en.wikipedia.org/wiki/Monkey_patch https://en.wikipedia.org/wiki/Monkey_patch
- apgwoz 4y agoNot only can you redefine classes and functions at runtime in CL, my understanding is that all references to them will automatically be updated to the new code (I think unless it’s compiled?). It was already mentioned that Python’s classes come up short here, and I bet there are lots of cases where functions, too, miss the mark.
- gumby 4y agoAll implementations can update the function because all function calls are resolved at runtime (e.g. the symbol is examined). I don’t know what happens with inlines and macros though — don’t know if any implementations recompile those.
- thelopa 4y agoIn most implementations, redefining an inline function or macro just means you may have some callers using the old code. SBCL warns if you redefine an inline function but doesn’t re-compile old code. Do note that the language has a different view on the matter though. In its list of assumptions compilers are allowed to make about the code they receive, we can see… > The definition of a function that is defined and declared inline in the compilation environment must be the same at run time. > Within a function named F, the compiler may (but is not required to) assume that an apparent recursive call to a function named F refers to the same definition of F, unless that function has been declared notinline. The consequences of redefining such a recursively defined function F while it is executing are undefined. > A call within a file to a named function that is defined in the same file refers to that function, unless that function has been declared notinline. The consequences are unspecified if functions are redefined individually at run time or multiply defined in the same file. http://clhs.lisp.se/Body/03_bbc.htm http://clhs.lisp.se/Body/03_bbc.htm So, technically the compiler is allowed to remove runtime function call indirection for functions defined in the same file and/or recursive calls (unless you use a NOTINLINE declaration). In practice, you probably won’t see that happen unless you crank up the optimizations when compiling. You are right that the language explicitly allows redefining functions in general > Except in the situations explicitly listed above, a function defined in the evaluation environment is permitted to have a different definition or a different signature at run time, and the run-time definition prevails.
- whartung 4y agoThe thing is the CLOS has specific support for updating existing class instances at runtime. Many languages do not. I don't know if Python does that.
- bmitc 4y agoIt's quite something to claim Python has features that basically very few if any languages have, languages that Python has decided to ignore. Python barely even has a workable REPL.
- laurencerowe 4y agoPython is dynamic and everything is ultimately some sort of object (including functions and classes) and can be modified. Taking the features mentioned one by one: > the ability to redefine functions In Python you have two options here, you can either update the module to have a new function: >>> mymodule.myfunc = mynewfunc But any existing references to `myfunc` will not be updated (e.g. if you did `import myfunc from mymoudle` instead of `import mymodule`). Alternatively you can update the function __code__: >>> def f1(): return 1 ... >>> def f2(): return 2 ... >>> def f3(): return f1() ... >>> f3() 1 >>> f1.__code__ = f2.__code__ >>> f3() 2 > and whole classes at runtime, You can take a similar approach with Python classes: >>> class A: pass ... >>> class B(A): pass ... >>> b = B() >>> A._a = '_a' >>> A.a = lambda self: self._a >>> b.a() '_a' You can also update SomeClass.__bases__ should you wish. > the ability to write new functions (/variables/classes etc) in the process of those redefinitions. As python is dynamic this can all be done at runtime. If you're not in a REPL you can call compile/exec/__import__ from your code. > Its debuggers are written in Lisp (completely extensible by you at runtime) offering a REPL right at the debug site. The Python debugger is written in Python and can be switched out. It's python code so like anything else can be changed at runtime. If you want something flashier than pdb you could use the IPython debugger: https://pypi.org/project/ipdb/ https://pypi.org/project/ipdb/ Edit: Want to modify an existing running python program but you didn't think to expose Python's dynamic extensibility before hand? No worries, just use parasite and inject arbitrary code into a running python process! https://pyrasite.readthedocs.io/en/latest/ https://pyrasite.readthedocs.io/en/latest/