в Clojure 1.2.x вы можете вызывать только локальные переменные, и они не могут пересекать вызовы функций.
начиная с Clojure 1.3.0 Clojure может использовать примитивные числа при вызове функций, но не через функции высшего порядка, такие как map
.
если вы используете clojure 1.3.0+, вы сможете выполнить это, используя подсказки типа
Как и при любой проблеме оптимизации clojure, первым шагом является включение (set! *warn-on-reflection* true)
, а затем добавление подсказок типа до тех пор, пока он больше не будет жаловаться.
user=> (set! *warn-on-reflection* true)
true
user=> (defn binary-search
[coll coll-size target]
(let [cnt (dec coll-size)]
(loop [low-idx 0 high-idx cnt]
(if (> low-idx high-idx)
nil
(let [mid-idx (quot (+ low-idx high-idx) 2) mid-val (coll mid-idx)]
(cond
(= mid-val target) mid-idx
(< mid-val target) (recur (inc mid-idx) high-idx)
(> mid-val target) (recur low-idx (dec mid-idx))
))))))
NO_SOURCE_FILE:23 recur arg for primitive local: low_idx is not matching primitive,
had: Object, needed: long
Auto-boxing loop arg: low-idx
#'user/binary-search
user=>
, чтобы удалить это, вы можете напечатать подсказку аргумента размера колла
(defn binary-search
[coll ^long coll-size target]
(let [cnt (dec coll-size)]
(loop [low-idx 0 high-idx cnt]
(if (> low-idx high-idx)
nil
(let [mid-idx (quot (+ low-idx high-idx) 2) mid-val (coll mid-idx)]
(cond
(= mid-val target) mid-idx
(< mid-val target) (recur (inc mid-idx) high-idx)
(> mid-val target) (recur low-idx (dec mid-idx))
))))))
понятно, что соединить автобокс в строке 10 с параметром coll-size, потому что он проходит через cnt
, high-idx
, mid-ixd
и т. Д., Поэтому я обычно подхожу к этим проблемам по типу намекая на все, пока я не найду тот, который заставляет предупреждения исчезнуть, затем удаляйте подсказки, пока они не исчезли