core.typed中的clojure.core.typed/cf何时计算并推断类型

core.typed中的clojure.core.typed/cf何时计算并推断类型,clojure,clojure-core.typed,Clojure,Clojure Core.typed,我不太理解下面解释的行为或clojure.core.typed/cf 我假设cf用于推断表单的类型 (t/cf (+ 1 2)) => Long 现在,这失败了 (t/cf (/ 1 0)) => Error 这向我表明,sexpr是在进行类型检查之前评估的。我原以为很长 定义自定义函数时: (t/ann my-fn [t/Any -> t/Num]) (defn my-fn [x] (assert (number? x)) (println "CALLED")

我不太理解下面解释的行为或
clojure.core.typed/cf

我假设
cf
用于推断表单的类型

(t/cf (+ 1 2)) => Long
现在,这失败了

(t/cf (/ 1 0)) => Error
这向我表明,sexpr是在进行类型检查之前评估的。我原以为
很长

定义自定义函数时:

(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的表单时,core.typed自动计算它。然而,这并不能解释为什么对于某些函数,它不进行求值。
(范围2)
中的
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))
(t/cf格式)(let[x格式](t/cf x))

core.typed
执行完全静态的类型检查

cf
的编译管道是
read->analyze->type check->eval

如果存在静态类型错误,则视为致命错误

否则将执行评估

(cf(/10))
抛出运行时错误,因为
(/10)
是类型良好的表达式

需要求值的原因与分析Clojure代码的实用性有关——如果分析代码而不求值,就会发生奇怪的事情