2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关如何工作的更多信息,请参阅关于 页面。

+1
ClojureScript

cljs

app:cljs.user=> (apply max [])
nil

clj

> (apply max [])
Execution error (ArityException) at redacted.ns/eval26821 (form- 
init217321140160545149.clj:741).
Wrong number of args (0) passed to: clojure.core/max

不确定我喜欢哪种行为(可能是 cljs?),但这在我们的应用程序中产生了我意想不到的结果。

2 答案

0

"意料之外的东西",因为不传参数调用 max 并不符合其合同约定。这是一种实际上未定义的行为。

感谢您的回答,您能否指出您所提到的合同?
函数的非常签名。
你说得很好。我会试着用这种签名中的函数零阶应用来更好地提出一个问题。谢谢!(
这实际上是不确定的代码。`max` 返回1个或多个数中的最大值。如果没有数,则没有答案。
0

可以说这是因为在 `max` 中没有合理的、通用的标识值(`min` 也没有),但你可以提供自己选择的值,例如 Integer/MIN_VALUE

user=> (apply max Integer/MIN_VALUE [])
-2147483648
user=> (apply max Integer/MIN_VALUE [2])
2
user=> 
我很欣赏这种想法,明确界限是个好主意。我认为,在这个后续问题中(https://ask.clojure.org/index.php/12051/apply-behaves-differently-in-clj-cljs-with-empty-argument),我们对困惑的根本原因有了更深的理解,JVM和JavaScript在应用错误数量的参数调用函数时存在不同的预期,我现在确信,在两个宿主上的行为是有道理的(而且它们之间的差异既可能是令人困惑的,但最终是可以接受的)。
作为补充,我认为如果你使用`reduce`而不是`apply`,可以遵循Rich Hickey的忠告,不要使用`reduce`的两个参数版本

  user=> (reduce max [])
  执行错误(参数异常)在用户/评估9(REPL:1)。
  向clojure.core/max传递了错误的参数数量(0)
  user=> (reduce max Integer/MIN_VALUE [])
  -2147483648
  user=> (reduce max Integer/MIN_VALUE [2])
  2
  user=>
...