这是我写的一个程序,我不知道为什么这是真的。
user=> (defn isClose [t1] (fn [t2] (and (<= (- t1 t2) 20)) (<= (- t2 t1) 20)))
#'user/isClose
user=> ((isClose 50) 10)
true
这不就变成这样了吗
user=> (and (<= 40 20) (<= -40 20))
false
你的括号错了。让我们添加一些换行符:
(defn isClose [t1]
(fn [t2]
(and (<= (- t1 t2) 20))
(<= (- t2 t1) 20)))
观察函数体有两个表达式,而不是一个:一个带有单个参数的
and
,后面跟着一个不相关的<=
调用。当一个函数体有多个表达式时,在评估所有早期表达式的副作用然后丢弃它们之后,返回最终表达式。你想写的是
(defn is-close [t1]
(fn [t2]
(and (<= (- t1 t2) 20)
(<= (- t2 t1) 20))))
确实如您所料。请注意,我还将函数名称修改为典型的 Clojure 命名约定。当然,这没有语义上的区别。叫它
close?
.就更典型了
手动平衡括号很棘手:当我阅读你的函数时,它看起来不错。只有在将它扩展到多行,并让一个像样的编辑器自动缩进以便布局与语义匹配之后,问题才变得明显。我建议使用支持 lisp 的编辑器,并为清晰起见插入换行符;你应该会发现缩进很有用。