繁体   English   中英

core.typed中的clojure.core.typed / cf什么时候评估并推断类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM