Это из Радости Clojure, 2nd Edition. http://www.manning.com/fogus2/
(defn mk-cps [accept? kend kont]
(fn [n]
((fn [n k]
(let [cont (fn [v] (k ((partial kont v) n)))]
(if (accept? n)
(k 1)
(recur (dec n) cont))))
n kend)))
Затем, чтобы сделать факториал:
(def fac (mk-cps zero? identity #(* %1 %2)))
Мое понимание:
- mm-cps генерирует функцию, которая принимает n, fn [n]
- функция внутри, fn [n k], изначально вызывается с n и kend
- функция продолжения cont [v] определяется как (вызов k с частичным применением kont с v) в качестве первого параметра и n в качестве второго параметра. Почему это будет написано с помощью
partial
вместо простого(k (cont v n))
? - если функция
accept?
проходит, затем завершите рекурсию, применяяk
к 1. - в противном случае
recur
возвращается к fn [n k] с уменьшенным n и с функцией продолжения. - kont не изменяется.
Правильно ли, что k
фактически не выполняется до окончательного (k 1)
?
Таким образом, (fac 3)
сначала раскрывается до (* 1 (* 2 3))
.