[英]when does clojure.core.typed/cf in core.typed evaluate and infer the type
我不太了解行为或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的表单时,然后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))
core.typed
执行完全静态的类型检查。
cf
的编译pipleline read -> analyze -> type check -> eval
。
如果存在静态类型错误,则认为是致命的。
否则将执行评估。
(cf (/ 1 0))
会引发运行时错误,因为(/ 1 0)
是类型正确的表达式。
需要评估的原因与分析Clojure代码的实用性有关—如果您分析代码然后不对其进行评估,则会发生奇怪的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.