我不太理解行为或clojure.core.typed/cf,如下所述。
我假设cf用于推断表单的类型。
(t/cf (+ 1 2)) => Long现在,这一切都失败了
(t/cf (/ 1 0)) => Error这表明在类型检查之前对sexpr进行了评估。我原以为是Long。
当我定义自定义函数时:
(t/ann my-fn [t/Any -> t/Num])
(defn my-fn [x]
(assert (number? x))
(println "CALLED")
x)我可以在同一个表达式中再次使用它,它失败了,这表明fn确实被调用了。
(t/cf (/ 1 (my-fn 0)) => Error, because it evaluates my-fn. no type inference here??然而,下面这些对我来说是没有意义的。
(t/cf (range)) => (t/ASeq t/AnyInteger)为什么在这种情况下函数范围没有计算,如果它确实计算了表达式,下面的示例应该返回相同的类型:
(t/cf (->> (range 2) vec)) => (t/AVec (t/U Short Byte Integer BigInteger Long BigInt))
(t/cf [0 1]) => [(t/HVec [(t/Val 0) (t/Val 1)]) {:then tt, :else ff}]但他们会返回不同的类型。
我的直觉是,它与常量有关,即当我输入包含t/Val's的表单时,core.typed会自动地对它进行评估。然而,这并不能解释为什么对于某些函数,它不对其进行评估。2在(range 2)中肯定是一个常量,那么为什么行为上会有这种差异。
如果表单是在类型检查之前计算的,那么下面的操作应该具有相同的行为
(t/cf (map inc (range 10))))
(t/cf (map #(inc %) (range 10))))但core.typed确实看到了不同之处。第二个示例失败了,因为匿名fn默认接收到一个t/Any,您不能在它上调用inc。因此,这意味着core.typed必须对表单进行一些分析,加上它还会对表单进行评估。我觉得有点困惑,我承认,也许有人能启发我。
编辑:一个简短的摘要
为什么在某些情况下,以下关系似乎是正确的,而不是所有的情况?
(t/cf form) <=> (let [x form] (t/cf x))发布于 2015-06-19 05:13:29
core.typed执行完全静态类型检查。
cf的编译pipleline是read -> analyze -> type check -> eval。
如果存在静态类型错误,则认为这是致命的。
否则,将执行评估。
(cf (/ 1 0))抛出一个运行时错误,因为(/ 1 0)是一个类型良好的表达式。
需要评估的原因与分析Clojure代码的实用性有关--如果分析代码而不对代码进行评估,就会发生奇怪的事情。
https://stackoverflow.com/questions/30889367
复制相似问题