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

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

+1
ClojureScript

In cljs

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

In 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`的两个arity版本

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