编译 Clojure 时获得更多有用的警告
Getting more useful warnings when compiling Clojure
在下面的函数中,我用cond
代替了case
。我花了很长时间才挑出这个功能。我正在学习 clojure,所以错误对我来说并不明显。当我尝试 运行 直到 map
函数的代码(使用 cursive/Intellij 调试器)时,Intellij 抱怨:There is no executable code at core.clj:144
。如果 clojure 编译器知道这一点,是否可以选择在编译时获得警告?编译器(或 lint)是否可以在我的代码中执行其他检查?
(defn uri-gen [uri fields line]
(let [remo "[//\:*?()<>|.%'\"&]"]
(cond (count fields)
0 (correct-uri ...)
1 (let ...)
(correct-empty
uri
(apply str
(map (fn [it] ...)))))))
不幸的是,Clojure 中的编译器警告和错误消息通常是简洁的、荒谬的,或者只是简单地缺失。
我不确定在这种情况下它是否有帮助,但您可以尝试 eastwood
Clojure lint 工具(请参阅 Clojure 工具箱中的其他工具)。我还广泛使用 Plumatic Schema,它帮助我避免了许多简单的类型错误。
这不是编译器的问题。
从编译器的角度来看,你写的非常有道理。 You've got an s-expression composed of an s-expression followed by more s-expressions - what's the problem? Lisp,例如 Clojure,几乎没有 "syntax" 编译器 "know" 的东西。例如,它不必担心诸如运算符优先级和 "if" 和 "while" 和 "until" 语句之类的愚蠢事情,以及其他语言的编译器会犹豫不决的所有其他事情。它不知道 cond
和 case
以及 and
和 whatever
做什么 - 它只知道,因为它们是未引用形式的第一个值,它们必须是一个函数;编译器在某种意义上可以 "find" 该函数,因此它可以创建代码来调用该函数;它后面还有一堆其他有效的表达式需要传递给函数。 (当然,那些其他表达式可能包含更多的 s 表达式,代表更多要调用的函数,我们继续往 Lisp 洞里走!)。开! 函数 必须对其传递的参数有某种意义,并执行函数应该执行的任何操作。编译器对所有这些一无所知 - 在非常非常简单的意义上,它只是读取 s 表达式并生成代码来调用函数。
如果您坚持将 case
-ish 参数传递给 cond
,编译器不关心.它会愉快地做你要求的事情。 cond
将(可能)吐出所有这些参数这一事实不是编译器需要处理的事情 - 这是程序员的问题。 Lisp/Clojure 将正确的责任放在程序员的肩上,这是它所属的地方。
Lisp 对程序员来说就像一种超能力。在合适的人手中,它是为人类服务的宝贵工具。在错误的人手中,这是灾难的根源。 Try not to be Tighten - 明智地使用你的力量。 :-)
在下面的函数中,我用cond
代替了case
。我花了很长时间才挑出这个功能。我正在学习 clojure,所以错误对我来说并不明显。当我尝试 运行 直到 map
函数的代码(使用 cursive/Intellij 调试器)时,Intellij 抱怨:There is no executable code at core.clj:144
。如果 clojure 编译器知道这一点,是否可以选择在编译时获得警告?编译器(或 lint)是否可以在我的代码中执行其他检查?
(defn uri-gen [uri fields line]
(let [remo "[//\:*?()<>|.%'\"&]"]
(cond (count fields)
0 (correct-uri ...)
1 (let ...)
(correct-empty
uri
(apply str
(map (fn [it] ...)))))))
不幸的是,Clojure 中的编译器警告和错误消息通常是简洁的、荒谬的,或者只是简单地缺失。
我不确定在这种情况下它是否有帮助,但您可以尝试 eastwood
Clojure lint 工具(请参阅 Clojure 工具箱中的其他工具)。我还广泛使用 Plumatic Schema,它帮助我避免了许多简单的类型错误。
这不是编译器的问题。
从编译器的角度来看,你写的非常有道理。 You've got an s-expression composed of an s-expression followed by more s-expressions - what's the problem? Lisp,例如 Clojure,几乎没有 "syntax" 编译器 "know" 的东西。例如,它不必担心诸如运算符优先级和 "if" 和 "while" 和 "until" 语句之类的愚蠢事情,以及其他语言的编译器会犹豫不决的所有其他事情。它不知道 cond
和 case
以及 and
和 whatever
做什么 - 它只知道,因为它们是未引用形式的第一个值,它们必须是一个函数;编译器在某种意义上可以 "find" 该函数,因此它可以创建代码来调用该函数;它后面还有一堆其他有效的表达式需要传递给函数。 (当然,那些其他表达式可能包含更多的 s 表达式,代表更多要调用的函数,我们继续往 Lisp 洞里走!)。开! 函数 必须对其传递的参数有某种意义,并执行函数应该执行的任何操作。编译器对所有这些一无所知 - 在非常非常简单的意义上,它只是读取 s 表达式并生成代码来调用函数。
如果您坚持将 case
-ish 参数传递给 cond
,编译器不关心.它会愉快地做你要求的事情。 cond
将(可能)吐出所有这些参数这一事实不是编译器需要处理的事情 - 这是程序员的问题。 Lisp/Clojure 将正确的责任放在程序员的肩上,这是它所属的地方。
Lisp 对程序员来说就像一种超能力。在合适的人手中,它是为人类服务的宝贵工具。在错误的人手中,这是灾难的根源。 Try not to be Tighten - 明智地使用你的力量。 :-)