ClojureScript

1.10.597 版本

2019 年 11 月 18 日
ClojureScript 团队

值得注意的更改

  • set/unioninto 的行为现在与 Clojure 保持一致。

  • subvec 的参数检查现在与 Clojure 保持一致。

  • 在数组上 apply vector 现在会正确克隆数组。

Google Closure 命名空间分析

编译器现在为 Google Closure 命名空间生成分析元数据。这意味着对于这些命名空间

  • REPL 功能,例如 docdirapropos 等,现在可以正常工作了。

  • 参数列表可用,从而启用参数个数检查。

  • 返回值类型可用,增强类型推断。

  • 将生成关于私有变量使用的警告。

为了说明,让我们 (require '[goog.crypt :as crypt]) 并探索它在 REPL 中。

现在,(dir crypt) 将列出该命名空间中的函数。

byteArrayToHex
byteArrayToString
hexToByteArray
...

文档字符串可用;(doc crypt/hexToByteArray) 将生成

-------------------------
goog.crypt/hexToByteArray
([hexString])
  /**
 * Converts a hex string into an integer array.
...

参数个数信息可用。向其中一个函数传递不正确的参数个数将生成参数个数警告。例如,(crypt/hexToByteArray "abc" 123) 将生成

WARNING: Wrong number of args (2) passed to goog.crypt/hexToByteArray at line 1 <cljs repl>

类型推断改进

此版本对 ClojureScript 的类型推断做出了几项改进。

对记录使用关键字查找的直接字段访问

这可以通过示例来说明

(defrecord Complex [re im])

(let [x (->Complex 1.1 2.7)]
   (:re x))

为最后一个表达式生成的代码将是 x.re。这可以比之前快 66% 到 450%。

count 对字符串和数组的专门化

如果将 count 应用于静态推断为字符串或数组的值,则生成的 JavaScript 将涉及直接访问 length 字段,而不是对 count 进行运行时调用。

例如,(count "abc") 将导致 "abc".length 被发出。根据上下文,这可能快几个数量级。

simple- / qualified- 谓词引起的推断

如果 simple-keyword?qualified-keyword? 对本地变量成立,则该本地变量将被推断为关键字。类似地,simple-symbol?qualified-symbol? 将导致本地变量被推断为符号。

这实质上将现有的 keyword?symbol? 的谓词引起的推断扩展到这些额外的核心谓词。

通过 and 的线程谓词引起的推断

这种类型推断改进或许可以通过示例来最好地解释。对于以下代码

(and (string? x) (zero? (count x)))

编译器现在将知道,如果上面的 and 中的第一个子句成立,那么在第二个子句中,x 必须是字符串类型。与上面提到的 count专门化相结合,这会导致生成有效的 JavaScript

typeof x === "string" && x.length === 0

不对 implements? 进行推断

这是一个内部的、但很重要的标准库优化:当 implements? 谓词对本地变量成立时,编译器会为涉及该本地变量的表达式生成更有效的函数分派代码。

不正确的跨参数 loop / recur 推断加宽

修复了涉及 loop / recur 推断加宽的一个极端情况,其中如果 loop 绑定的本地变量用作 recur 目标,则可能会发生不正确的推断。

动态变量现在被正确地推断为具有 any 类型

修复了一个推断错误,该错误导致动态变量被错误地推断为具有其初始化值类型。这是不正确的,因为动态变量可以在运行时重新绑定为与初始化值类型不同的类型的值。

性能改进

优化 IAssociative 值上的 assoc

核心 assoc 函数中的一个优化使得它在对 IAssociative 值(常见情况)进行 assoc 时更快。

例如,将键值对 assoc 到映射上,在 V8 中可以快 24%,在 JavaScript 核心中的可以快 11%,这对这个经常使用的核心函数来说是一个巨大的性能提升。

ci-reduce 中将 coll 标记为 not-native

这是一个影响标准库的重要内部优化,它在减少 IIndexedICounted 的集合时提高了性能。

改进 cljs.source-map.base64/encode 的性能

这提高了源映射生成中大量使用的函数的性能,在我们的一项测量中将性能提高了 17%。

变更列表

有关 ClojureScript 1.10.597 中所有更新的完整列表,请参阅 变更

贡献者

感谢所有为 ClojureScript 1.10.597 做出贡献的社区成员。

  • Dieter Komendera

  • Erik Assum

  • Herald

  • Martin Kavalar

  • Martin Kučera

  • Michiel Borkent

  • Roman Liutikov

  • Seçkin Kükrer

  • Thomas Mulvaney