Clojure - protocols/multimethods 溢出
Clojure - protocols/multimethods overflow
为了更好地理解 Clojure 协议,我问自己它们的行为是否与 cond
完全一样。例如这个函数可能会溢出:
(defn my-cond [n]
(cond
(< n 0) (my-cond (inc n))
(> n 0) (my-cond (dec n))
:else "zero"))
> (my-cond 3)
;; "zero"
> (my-cond 99999999)
;; java.lang.WhosebugError
例如,假设我现在使用一个协议来进行等效(即递归协议调用)。它会以任何方式改变堆栈可能爆炸的方式吗?
我的直觉说不(怎么可能),但是(1)我不了解协议内部结构和(2)因为它们使代码耦合度降低,可能更容易引入这种循环,因此能够防止它是有意义的。
协议和多重方法是否以与普通方法调用相同的方式使用堆栈?
是;函数、方法、多重方法和协议都将它们的上下文压入堆栈。然而,协议不同于具有条件或多重方法的函数调用,因为协议公开类型的单一分派,而 JVM 在这方面非常快。类型还使协议可以从 Java 以动态函数不可用的方式使用。所以是的,它们在语义上是相同的,但它们也满足了速度和与底层平台互操作的实际需求。
为了更好地理解 Clojure 协议,我问自己它们的行为是否与 cond
完全一样。例如这个函数可能会溢出:
(defn my-cond [n]
(cond
(< n 0) (my-cond (inc n))
(> n 0) (my-cond (dec n))
:else "zero"))
> (my-cond 3) ;; "zero" > (my-cond 99999999) ;; java.lang.WhosebugError
例如,假设我现在使用一个协议来进行等效(即递归协议调用)。它会以任何方式改变堆栈可能爆炸的方式吗?
我的直觉说不(怎么可能),但是(1)我不了解协议内部结构和(2)因为它们使代码耦合度降低,可能更容易引入这种循环,因此能够防止它是有意义的。
协议和多重方法是否以与普通方法调用相同的方式使用堆栈?
是;函数、方法、多重方法和协议都将它们的上下文压入堆栈。然而,协议不同于具有条件或多重方法的函数调用,因为协议公开类型的单一分派,而 JVM 在这方面非常快。类型还使协议可以从 Java 以动态函数不可用的方式使用。所以是的,它们在语义上是相同的,但它们也满足了速度和与底层平台互操作的实际需求。