5 ms·
Smalltalk has a meta API that is designed to allow introspection and modification of both static and dynamic code entities [1,2]. Static entities such as class
by robertkrahn01 9y ago
Smalltalk has a meta API that is designed to allow introspection and modification of both static and dynamic code entities [1,2].
Static entities such as classes and methods (and depending on your Smalltalk implementation namespaces and object versions) can be modified at runtime, i.e. while your program is running you can make a change and get an immediate effect. This is now known as "live" programming, however, it is notably different from your typical "hot reload" implementation in that it knows how to apply changes for individual code entities. E.g. if you modify a method you don't need to reload the entire class or module or entire runtime. For me, this feature alone makes for a big productivity increase.
Dynamic entities such as stack frames can also be reified by the meta interface. This allows to inspect and modify runtime processes, e.g. inside a "debugger" [3]. Note that the debugger allows to modify and create new code while your are debugging. This is a powerful feature because it means that you get access to runtime objects inside of it. Ever wondered what object gets passed into your method at a certain point, what methods it knows, what properties it has? Just try it out and see for yourself!
An interesting analogy to describe this experience: [4].
For a deeper description about the ideas behind that see Design Principles Behind Smalltalk [5].
Also, most Lisp implementations provide the same kind of meta interface, and CLOS arguably provides a more flexible and higher level abstraction of these ideas [6].
As for similar environments I have worked on, there is Lively for JavaScript [7] and cloxp for Clojure [8]
[1] http://sdmeta.gforge.inria.fr/FreeBooks/ByExample/31%20-%20Chapter%2029%20-%20Meta-Programm.pdf http://sdmeta.gforge.inria.fr/FreeBooks/ByExample/31%20-%20C...
[2] Chapters 16 http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook....
[3] https://www.youtube.com/watch?v=1kuoS796vNw https://www.youtube.com/watch?v=1kuoS796vNw
[4] http://simberon.blogspot.nl/2013/01/swimming-with-fish.html http://simberon.blogspot.nl/2013/01/swimming-with-fish.html
[5] https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk....
[6] https://mitpress.mit.edu/books/art-metaobject-protocol https://mitpress.mit.edu/books/art-metaobject-protocol
[7] http://lively-next.org/ http://lively-next.org/
[8] http://cloxp.github.io/ http://cloxp.github.io/
- catnaroek 9y ago> Static entities such as classes and methods (and depending on your Smalltalk implementation namespaces and object versions) can be modified at runtime Then it's not static.
- coldtea 9y agoStatic doesn't mean constant or immutable. One can alter static stuff at runtime in all kinds of languages.
- catnaroek 9y agoThen again it's not static. In programming language semantics, there is a distinction between “static semantics” (e.g., lexical scope, type checking) and “dynamic semantics” (execution). Not having a static semantics (or, rather, having a trivial one) is fine, but it doesn't suddenly allow you to call parts of the dynamic semantics “static”. What's with kids again not knowing basic computer science?
- robertkrahn01 9y agoYou are right, my usage of the term static does not go back to a well defined notion, I used it for brevity. What I meant is to make a distinction between entities describing the (runtime) system's state (classes, methods) vs. the entities used in the system's execution (stack frames, message sends).
- EdwardCoffin 9y agoThese points about modifying things at run time are important, and not all Smalltalk programmers do this nor even understand it, simply using it as another language and writing something like C in it. Another thing you can do that isn't explicitly mentioned above is "dropToFrame" where you can point to any one of the calling methods out of the call stack and have the process revert to a state so it is like it only just entered that method. I occasionally have debugged bugs that only surfaced rarely simply by having a tester call me when the problem manifests, and I spent a few hours with that function call live, repeatedly taking runs through to see what happened then reverting to a state where the problem was about to manifest but not so early that everything was lost. You can also write debugging code of arbitrary complexity. You could write a 20-line query to do consistency checking of some data structure that is being operated on to satisfy yourself of various things you assume are true. You can make a special debugging subclass of some ubiquitous class, tell one particular instance of the class to become of the subclasses type which will then do all sorts of extra bookkeeping (perhaps recording stack frames every time it is invoked to see who asks it to do things). You can execute a windowUnderMouse call to get an inspector on whatever widget is under your mouse pointer to make sure that the button you are looking at is in fact the one you think you are looking at. I used this to find a problem once where someone had subclassed some complicated window to add some functionality, and one of the buttons didn't work any more: turned out they were creating the same button again in the subclass constructor, which was overlaying the original's button (the one with all the event handlers). I think some of this stuff might be more common in other languages now, but it wasn't in the mid-nineties. I know Java had a limited version of drop-to-frame a number of years ago, but it had some pretty cramping restrictions.