I believe this is a typical type-sending mechanism, even for non-dynamic languages other than OO, based on this article about the JHC Haskell compiler and how it implements type classes. The consequence of this article is that most Haskell compilers implement type classes (type dispatch types) by passing dictionaries. Its alternative is a direct case analysis, which is probably not applicable to dynamically typed languages, since you do not know in advance what the types of components of your expression will be. On the other hand, it is also impossible to expand at runtime.
Regarding dynamic languages other than OO, I don't know many examples outside of Lisp / Scheme. Generic Lisp CLOS makes Lisp a proper OO language and provides dynamic dispatch as well as multiple dispatch (you can add or remove common methods and methods at runtime, and they can disable the type more than just the first parameter). I don’t know how this is usually implemented, but I know that this is usually an add-on, not an integrated tool, which implies using the functionality available to a potential monkey patcher, and some versions have been criticized for their lack of speed (CLISP, I I think, but they may have decided that). Of course, you could implement this type of concurrency mechanism in OO, and you will probably find many examples of this.
If you used purely functional persistent maps or dictionaries, you could certainly realize this ability without even needing a chain of inherited maps; since you “modify” the map, you get the new map back, but all existing links to the old map will still be valid and will consider it as the old version. If you use the language with this tool, you can interpret it by placing a type-> function map in the Reader monad and wrapping your interpreter in it.
source share