Sono confuso su come def e lasciare variabili di binding in modo diverso. Qualcuno può spiegarmi perché questo funziona:Funzione di ricorrenza interna let
(def leven
(memoize (fn [x y]
(cond (empty? x) (count y)
(empty? y) (count x)
:else (min (+ (leven (rest x) y) 1)
(+ (leven x (rest y)) 1)
(+ (leven (rest x) (rest y)) (if (= (first x) (first y)) 0 1))
)
)))
)
Ma quando provo a dichiarare la funzione come lasciarlo fallisce la compilazione:
(def leven
(let [l (memoize (fn [x y]
(cond (empty? x) (count y)
(empty? y) (count x)
:else (min (+ (l (rest x) y) 1)
(+ (l x (rest y)) 1)
(+ (l (rest x) (rest y)) (if (= (first x) (first y)) 0 1))
)
)
))]
(l x y)
)
)
EDIT: Questo funziona, utilizzando la tecnica ha mostrato da Ankur.
(defn leven [x y]
(let [l (memoize (fn [f x y]
(cond (empty? x) (count y)
(empty? y) (count x)
:else (min (+ (f f (rest x) y) 1)
(+ (f f x (rest y)) 1)
(+ (f f (rest x) (rest y)) (if (= (first x) (first y)) 0 1))
)
)
))
magic (partial l l)]
(magic x y)
)
)
Molto interessante. Quindi in pratica stai solo passando la funzione come argomento in modo che il compilatore non si confonda su di esso non essendo definito. Non posso provarlo ora, ma ho intenzione di provare questo approccio più tardi. – onit