如何猴子修补通用类型标记函数表
我发现在 sicp - 使用标签+名称类型的表 ->您可以从中获取或添加的函数。
我想知道,这是动态非 OO 语言的典型类型分派机制吗?
另外,使用表的链接列表来猴子路径的典型方法是什么(如果您在第一个表中没有找到它,请递归地尝试下一个表)?将本地范围内的表重新绑定到修改后的副本?等等?
I found it interesting to read on one of the ways that you can do functional dynamic dispatch in sicp - using a table of type tag + name -> functions that you can fetch from or add to.
I was wondering, is this a typical type dispatch mechanism for a dynamic non OO language?
Also what would be the typical way to monkey path this, using a chaining list of tables(if you don't find it in the first table try next table recursively)? Rebind the table within local scope to a modified copy? ect?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信这是一种典型的类型分派机制,即使对于非动态非 OO 语言也是如此,基于 this关于 JHC Haskell 编译器及其如何实现类型类的文章。文章中的含义是,大多数 Haskell 编译器通过传递字典来实现类型类(一种类型分派)。他的替代方案是直接案例分析,这可能不适用于动态类型语言,因为您事先不知道表达式的组成部分的类型是什么。另一方面,这在运行时也是不可扩展的。
至于动态非 OO 语言,我不知道 Lisp/Scheme 之外有多少例子。 Common Lisp 的 CLOS 使 Lisp 成为一种合适的 OO 语言,并提供动态分派和多重分派(您可以在运行时添加或删除泛型和方法,并且它们可以关闭第一个参数以外的类型)。我不知道这通常是如何实现的,但我确实知道它通常是一个附加工具而不是内置工具,这意味着它使用了潜在的猴子修补程序可用的功能,而且某些版本因速度不够而受到批评(CLISP,我认为,但他们可能已经解决了这个问题)。当然,您也可以在面向对象的语言中实现这种类型的并行调度机制,并且您可能会找到很多这样的示例。
如果您使用纯功能性持久映射或字典,那么您当然可以实现此功能,甚至不需要继承映射链;当您“修改”地图时,您会得到一张新地图,但对旧地图的所有现有引用仍然有效,并将其视为旧版本。如果您正在使用此功能实现一种语言,您可以通过将类型->函数映射放入 Reader monad 并将您的解释器包装在其中来解释它。
I believe this is a typical type dispatch mechanism, even for non-dynamic non-OO languages, based on this article about the JHC Haskell compiler and how it implements type classes. The implication in the article is that most Haskell compilers implement type classes (a kind of type dispatch) by passing dictionaries. His alternative is direct case analysis, which likely would not be applicable in dynamically typed languages, since you don't know ahead of time what the types of the constituents of your expression will be. On the other hand, this isn't extensible at run-time either.
As for dynamic non-OO languages, I'm not aware of many examples outside Lisp/Scheme. Common Lisp's CLOS makes Lisp a proper OO language and provides dynamic dispatch as well as multiple dispatch (you can add or remove generics and methods at run-time, and they can key off the type of more than just the first parameter). I don't know how this is usually implemented, but I do know that it is usually an add-on facility rather than a built-in facility, which implies it's using functionality available to the would-be monkey-patcher, and also that certain versions have been criticized for their lack of speed (CLISP, I think, but they may have resolved this). Of course, you could implement this type of parallel dispatch mechanism within an OO language as well, and you can probably find plenty of examples of that.
If you were using purely-functional persistent maps or dictionaries, you could certainly implement this faculty without even needing the chain of inherited maps; as you "modify" the map, you get a new map back, but all the existing references to the old map would still be valid and see it as the old version. If you were implementing a language with this facility you could interpret it by putting the type->function map in the Reader monad and wrapping your interpreter in it.