2015-05-22 2 views
5

Я попытался запустить два факторных функции с тем же алгоритмом, один в Scala, а другой в Clojure:Разница между Scala РЕПЛ и Clojure REPL - компилировать скорость

// 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?

ответ

10

REPL имеет довольно специфическое значение. «True REPL» будет соответствовать следующему шаблону: Прочитать Eval Print Loop. Можно построить REPL в Clojure всего несколько строк:

(loop [] 
    (let [string (read-line) 
     data (read-string line) 
     result (eval data)] 
    (println result) 
    (recur))) 

Здесь вы видите основные части истинной замены. read-line читает текст с консоли. read-string преобразует эту строку в данные (списки, векторы, числа и т. Д.). eval оценивает данные, возвращающие результат, и println выводит результат.

Некоторые утверждают (и я согласен), что только те системы, которые следуют этим четырем шагам, могут быть названы repl. И некоторые также отметили бы, что Scala не является homoiconic, и поэтому не может по-настоящему иметь repl.

По homoiconic, я имею в виду, что компилятор работает с одними и теми же структурами данных, создаваемыми читателем языка, и управляется основными конструкциями языка. Например, это совершенно правильный код Clojure:

(eval (list (symbol "+") 41 1))) ; evals to 42 

Так вот суть дискуссии по поводу «реальных» консолей REPL. Только homoiconic языки, такие как lisp (и, возможно, пролог?), Могут иметь настоящие REPL. Все остальные должны действительно называться «интерактивными переводчиками».

Что касается скорости движения. Вероятно, это связано с сложностью компилятора. Компилятор Clojure составляет всего около 10 тыс. Строк довольно линейного кода. Одиночный проход, ничего особенного. Компилятор Scala довольно продвинутый, поддерживающий такие вещи, как статическая типизация и несколько проходов. Эти дополнительные функции не нужны на языке Clojure, и они, как правило, замедляют работу компилятора.

+1

Хм. Я бы подумал, что если взаимодействие с командной строкой связано с отдельными этапами чтения, оценки и печати, этого будет достаточно для REPL-ness, независимо от того, является ли язык гомоциконным или нет. Я бы не назвал что-то интерпретатором, если он компилируется до его выполнения. Конечно, существуют всевозможные промежуточные случаи между «исполнением одного выражения за раз, один за другим» и «перевод и оптимизация больших фрагментов кода до какого-то« машинного »языка, а затем выполнение». Однако, я не думаю, что это имеет значение! – Mars

+0

Связанные: http://stackoverflow.com/questions/5671214/is-lisp-the-only-language-with-repl –

 Смежные вопросы

  • Нет связанных вопросов^_^