Clojure 静态类型,第 2 部分
这是我之前关于 Clojure 静态类型的问题的后续内容。
我浏览了编译器的Java源代码,有几个地方检查了*warn-on-reflection*
的值,但是当我编译以下代码时,我只得到一个运行时错误:
(defn div-2 [^String s] (/ 2 s))
是否有任何情况下此代码不应给出编译时警告(实际上不会)?让编译器对以下代码发出警告有多困难:
(defn get-length [^String s] (.length s))
(defn test-get-length [] (get-length 2.0))
谢谢。
This is a follow-up to my previous question on Clojure static typing.
I browsed the Java source code for the compiler and there are several places where it checks the value of *warn-on-reflection*
, but when I compile the following code, I only get a run-time error:
(defn div-2 [^String s] (/ 2 s))
Are there any circumstances where this code should not give a compile-time warning (it does not)? How difficult would it be to have the compiler give a warning on the following code:
(defn get-length [^String s] (.length s))
(defn test-get-length [] (get-length 2.0))
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是编译器不跟踪 def 变量的类型。所以是的,在你的简单例子中,这是可能的。但是您多久传递一次文字呢?在实际的程序中很少见。
让类型像在真正的静态类型语言中那样“流动”将需要大量的返工。您必须通过变量、动态反弹变量、取消引用等来跟踪类型信息。然后,您仍然会遇到从集合/序列中提取项目的问题,这意味着泛型类型,这是一个巨大 蠕虫......
Clojure 中的类型注释从来都不是为了在编译时提供类型安全 - 它们只是允许编译器生成更优化的代码(以运行时错误为代价)如果遇到意外的类型。)
使用完整的静态类型信息来检测编译器可能是可能的,但此时您已经很大程度上重写了语言,并且您必须在如何处理类型方面做出许多决定和权衡。它真的不再是 Clojure 了。
The problem is that the compiler doesn't track the type of
def
'd vars. So yes, in your simple example, it would be possible. But how often do you pass a literal? Rarely, in a real program.Making types "flow through" like they do in a real statically typed language would require an extensive amount of reworking. You'd have to track type information through vars, dynamically rebound vars, dereferences, etc. And then you still have the issue of pulling items out of collections/sequences, which implies genericized types, which is a huge can of worms...
Type annotations in Clojure were never intended to provide type-safety at compile time - they just allow the compiler to generate more optimized code (at the expense of a run-time error if an unexpected type is encountered.)
Instrumenting the compiler with full static typing information might be possible, but at that point you've largely rewritten the language, and you'll have had to make many decisions and tradeoffs in how types are handled. It really wouldn't be Clojure anymore.
与其尝试修改编译器,为什么不编写一个单独的工具来扫描 Clojure 代码文件并警告类型违规呢?您可以使用宏来开发自己的类型表示法,这些宏会折叠成正常的非类型化 Clojure 代码。但是当您运行静态类型检查器时,它会理解类型并输出警告。
如果您准备迎接稍大的挑战,您甚至可以让它执行类型推断,从而减轻符号的负担。
Rather than trying to modify the compiler, why not write a separate tool that just scans a Clojure code file and warns about type violations? You could develop your own type notation using macros that just collapse into normal untyped Clojure code. But when you run the static type checker, it would grok the types and output warnings.
If you were up for a slightly bigger challenge, you could even have it perform type inference thus lowering the burden of notation.
继该线程之后,现在有一个项目旨在将渐进式输入引入 clojure(如 Dart 等)。值得测试一下:
Typed-Clojure
如果有人也可以在实际使用后给出一些反馈...
Following up that thread, there is now a project aiming at bringing gradual typing into clojure (like Dart, etc.). Worth testing it :
Typed-Clojure
If someone can also give some feedback after real use...