以下Clojure代码实际上是错误的:
(defn divv [x y z] (if (< x y) z (divv ((- x y) y (+ z 1)))))
正确的应该是:
(defn divv [x y z] (if (< x y) z (divv (- x y) y (+ z 1))))
但它传递了Clojure REPL,并返回一个函数。但在调用它时(例如(divv 3 2 0)
,错误将显示
ClassCastException java.lang.Long无法强制转换为clojure.lang.IFn user / divv(NO_SOURCE_FILE:1)
问题是,为什么在定义divv
时未检测到错误?由于divv
已被定义为函数,因此需要3个参数,为什么(divv ((- x y) y (+ z 1)))
可以通过测试?
答案 0 :(得分:3)
根据我的经验,语言设计似乎有两种基本的思想流派:
学校#1(“静态分析”,“Deus Ex Compiler”或“Mad Megalomaniac”学校)认为,检测可能导致的许多/大多数/所有可能条件是可能的,也是可取的在运行时出现的问题,其特点是A)大量的静态类型信息(静态分析的有趣之处是没有静态数据可以操作?),B)大规模和复杂的编译器,需要消化,筛选和对所有静态数据进行排序,以及C)大量编译时错误消息,这些消息旨在阻止运行时错误。
学校#2(“动态分析”,“坚果教授”或“我 - 我们会在运行时将其弄清楚”学校)认为,因为静态分析无法确定可能发生的一切在运行时出错(因为有些东西超出了ken,即使是最静态的静态分析:-),这不值得打扰,并且无论如何它都将在洗涤中出现。这些语言/系统的特点是A)小型编译器只能在有限的信息上运行,B)更复杂的运行时支持,以便检测静态分析可能检测到的错误,C)最小或无输入信息,以及D)更多的运行时错误你可以动摇编译手册。
我自己,我喜欢“动态分析”学校的语言,只因为它使开发软件变得更有趣。如果您从未使用过变量没有数据类型的语言,并且编译某些东西不需要休息时间,那么您可能需要尝试使用动态类型语言(例如Smalltalk或Clojure) 。灵活性很有趣。