由sfnelson发表的评论
抱歉,Stuart,我们才刚刚注意到您的回复,多亏了http://ashtonkemerling.com/blog/2016/06/11/my-increasing-frustration-with-clojure/上的宣传。
我将尝试介绍我们的使用案例,以提供背景,但请理解,这个问题仅仅是关于一个看起来和感觉像公共API函数(谁能想到'eval'会是私有的)的行为的不一致。
我们公司使用Clojure构建了一个云平台,该平台通过从数据库加载模块来响应用户请求进行计算。模块是可信代码,但它们与我们主平台独立,因此可能同时运行多个相同模块的多个版本(我们希望避免命名空间冲突)。我们考虑了许多方法来防止模块相互干扰,包括运行单独JVM的容器和微服务,但为了使简单查询(如“此输入是否有效?”)有可接受的反应时间,我们希望在Web服务器相同的JVM中运行简单查询。
我们用于响应用户查询的一般方法是为我们的计算构建一个命名空间(这可能需要从计算模块加载其他命名空间),然后在构建的上下文中评估表达式。我们有一个LRU缓存来存储模块命名空间,但评估仍然会产生大量元空间抖动,我们通过使用Clojure解释器来处理简单查询(评估太慢)来减轻这一现象。
当实现我们的LRU模块命名空间缓存时,我们想尝试将模块命名空间加载到自己的类加载器中,以帮助追踪类生命周期和GC,并希望允许多个命名空间版本并存。但后来我们得出结论,这是行不通的,因为Clojure与命名空间相关的全局查找太多,所以我们现在在加载时对模块命名空间进行预处理并执行名称混淆,并在缓存过期时显式注销已加载的命名空间,以便它们的类可以被收集。我们避免在模块中使用像multimethods和protocols这样的语言功能,它们使用全局变量。
再次,我们并不是在寻找Clojure团队为我们实现容器(尽管这肯定是一个很好的功能!),这只是我们注意到API和实现之间的一个不一致性。Java-interop eval的预期入口点是什么?