Оценка части Clojure cond - PullRequest
6 голосов
/ 18 января 2009

Пытаясь выполнить упражнение 1.16 (итеративная версия fast-exp) в разделе «Структура и интерпретация компьютерных программ» с Clojure, я придумал следующее:

(defn fast-it-exp [base exp res]
  (cond (= exp 0) res
  (odd? exp) fast-it-exp base (- exp 1) (* base res)
  :else fast-it-exp base (/ exp 2) (* base base res)))

Испытание:

user=> (fast-it-exp 0 0 10)
10   ;yep
user=> (fast-it-exp 2 2 2)
1     ;no...
user=> (fast-it-exp 1 1 1)
#<user$fast_it_exp__59 user$fast_it_exp__59@138c63>    ;huh?!

Кажется, что "нечетная" часть выражения cond возвращает функцию вместо оценки. Зачем? Я пытался поместить скобки вокруг выражений после предикатов, но это, кажется, неправильный синтаксис, это лучшее, что я смог придумать. Я использую версию 1146 Clojure.

Ответы [ 2 ]

11 голосов
/ 18 января 2009

Попробуйте это:

 (defn fast-it-exp [base exp res]
  (cond (= exp 0) res
        (odd? exp) (fast-it-exp base (- exp 1) (* base res))
        :else (fast-it-exp base (/ exp 2) (* base base res))))

У меня нет REPL под рукой, но похоже, что вы хотите.

6 голосов
/ 20 января 2009

По сути, то, что вы написали, может быть переформатировано как:

(defn fast-it-exp [base exp res]
  (cond
    (= exp 0) res
    (odd? exp) fast-it-exp
    base (- exp 1)
    (* base res) :else
    fast-it-exp base
    (/ exp 2) (* base base res)))

Итак:

user=> (fast-it-exp 0 0 10) ; (= exp 0) => res
10   ;yep
user=> (fast-it-exp 2 2 2)  ; base => (- exp 1)
1     ;no...
user=> (fast-it-exp 1 1 1)  ; (odd? exp) => fast-it-exp
#<user$fast_it_exp__59 user$fast_it_exp__59@138c63>    ;huh?!
...