我已经使用Scala语言几个月了,我已经在Scala中创建了几个项目.我发现Scala REPL(至少它的IntelliJ工作表实现)对于快速开发非常方便.我可以编写代码,看看它做了什么,这很好.但我只为函数(不是整个程序)执行该过程.我无法启动我的应用程序并在现场更改它.或者至少我不知道如何(所以,如果你知道欢迎你给我一些建议).
几天前,我的同事告诉了我关于Clojure REPL的事.他使用Emacs进行开发过程,他可以现场更改代码,无需重新启动即可查看结果.例如,他启动该过程,如果他改变了函数的实现,他的代码将改变他的行为而不重新启动.我想用Scala语言做同样的事情.
PS我想讨论哪种语言更好,功能编程也不比面向对象更好.我想找到一个好的解决方案.如果Clojure是更好的任务语言,那么就让它成为现实.
arr*_*dem 18
简短的回答是Clojure旨在使用一个非常简单的单通道编译器,它一次读取和编译单个s表达式或表单.无论好坏,都没有全局类型信息,没有全局类型推断,也没有全局分析或优化.Clojure使用clojure.lang.Var实例通过从文本符号到事务值的一系列哈希映射来创建全局绑定.def表格全部在此全局绑定映射中创建全局范围的绑定.因此,在Scala中,"函数"(方法)将被解析为给定JVM类上的实例或静态方法,在Clojure中,"函数"(def)实际上只是对var绑定表中的条目的引用.调用函数时,没有到另一个类的静态链接,而是通过符号名引用var,然后取消引用以获取clojure.lang.IFn随后调用的对象的实例.
这个间接层意味着一次只能重新评估一个定义,并且重新评估对于重新定义的var的所有客户端都是全局可见的.
相比之下,当Scala中的定义发生更改时,scalac必须重新加载已更改的文件,宏扩展,类型推断,类型检查和编译.然后由于JVM上的类加载的语义,scalac还必须重新加载所有依赖于更改的类中的方法的类.此外,作为已更改类的实例的所有值都将变为垃圾.
这两种方法都有其优点和缺点.显然,Clojure的方法实现起来比较简单,但是由于持续的函数查找操作,由于缺乏静态类型而忘记了正确性问题,因此它在性能方面需要付出持续的成本.这可以说适用于在短时间内发生大量变更的上下文(交互式开发),但是当代码大部分是静态的时(部署,因此是Oxcart),它不太适合上下文.我所做的一些工作表明,由于缺乏静态方法链接,Clojure程序的减速量大约为16-25%.这不是叫Clojure缓慢或Scala快,他们只是有不同的优先级.
Scala选择在前面做更多的工作,以便编译的应用程序将表现得更好,这可能更适合应用程序部署,当很少或没有重新加载时,但是当你想做很多小的改变时证明是拖累.
由于尼古拉斯对我的GSoC工作影响很大,因此我手头有一些关于按照出版顺序或多或少按时间顺序编译Clojure代码的材料.
我想这让我处于一个不愉快的地方,简单地说"对不起,Scala并不像Clojure那样设计"关于代码热插拔.