我尝试使用相同的算法运行两个阶乘函数,一个在Scala中,另一个在Clojure中:
// Scala:
def factorial(n:Int) = (1 to n).foldLeft(1: BigInt)(_*_)
-
;; Clojure:
(defn factorial [x]
(reduce * (range 1N (inc x))))
第一次将函数输入到REPL时,Clojure评估(函数定义,不计算阶乘),没有任何明显的延迟;而scala只是暂停了一会儿。 (虽然很短很短,但仍然很明显。)
当我应用函数来计算阶乘时,两者都会非常快地返回结果。
我想对REPL有一个基本的了解。两个REPL之间有什么区别吗? Scala REPL是真正的REPL吗?
答案 0 :(得分:10)
REPL具有相当具体的含义。 “True REPL”将符合以下模式:Read Eval Print Loop。人们可以在几行中构建一个cloj中的REPL:
(loop []
(let [string (read-line)
data (read-string line)
result (eval data)]
(println result)
(recur)))
在这里,您可以看到真正的repl的主要部分。 read-line
从控制台读取一些文本。 read-string
将该字符串转换为数据(列表,向量,数字等)。 eval
评估返回结果的数据,println
打印结果。
有些人会争辩(我同意)只有那些遵循这四个步骤的系统才有资格被称为repl。还有一些人还会指出Scala不是同性恋,所以不能真正有一个repl。
通过homoiconic,我的意思是编译器在语言读者生成的相同数据结构上运行,并且由语言的核心结构操纵。例如,这是完全有效的Clojure代码:
(eval (list (symbol "+") 41 1))) ; evals to 42
这就是关于“真实”REPL的辩论的要点。只有像lisp(也许是prolog?)这样的homoiconic语言可以拥有真正的REPL。所有其他人应该真正被命名为“互动口译员”。
就速度而言。这可能是由于编译器的复杂性。 Clojure编译器只有大约10k行非常线性的代码。单程,没什么特别的。 Scala编译器非常先进,支持静态类型和多次传递等功能。像Clojure这样的语言不需要这些额外的功能,并且它们确实会使编译器慢下来。