这句话在 Clojure 中如何成立?

mma*_*nry 3 clojure

这是来自我编写的程序,我不知道为什么这是真的。

user=> (defn isClose [t1] (fn [t2] (and (<= (- t1 t2) 20)) (<= (- t2 t1) 20)))
#'user/isClose
user=> ((isClose 50) 10)
true
Run Code Online (Sandbox Code Playgroud)

这不就减少到这个程度了吗?

user=> (and (<= 40 20) (<= -40 20))                                            
false
Run Code Online (Sandbox Code Playgroud)

ama*_*loy 8

你的括号错了。让我们添加一些换行符:

(defn isClose [t1] 
  (fn [t2] 
    (and (<= (- t1 t2) 20)) 
    (<= (- t2 t1) 20)))
Run Code Online (Sandbox Code Playgroud)

请注意,函数体有两个表达式,而不是一个:一个and带有单个参数,后跟一个不相关的<=调用。当函数体有多个表达式时,在评估所有早期表达式的副作用并丢弃它们之后,返回最终表达式。你本来想写的是

(defn is-close [t1] 
  (fn [t2] 
    (and (<= (- t1 t2) 20)
         (<= (- t2 t1) 20))))
Run Code Online (Sandbox Code Playgroud)

其行为确实如您所料。请注意,我还将函数名称修改为典型的 Clojure 命名约定。当然,这没有语义上的区别。命名它会更典型close?

手动平衡括号很棘手:当我阅读你的函数时,它看起来很好。只有在将其扩展到多行并让一个像样的编辑器自动缩进以使布局与语义相匹配之后,问题才变得明显。我建议使用支持 lisp 的编辑器,并插入换行符以保持清晰;你应该会发现缩进很有帮助。

  • 为了进一步简化,只需编写 `(&lt;= (abs (- t1 t2)) 20)` (2认同)