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

欢迎!请参阅 关于 页面以了解有关此处的更多信息。

+4 投票
Clojure
编辑

目前 clojure.core/*assert* 的默认值是 true

这对库的创建者和消费者有一些影响。

作为库的创建者,您不能只在开发/测试中添加断言以帮助您,因为这会让大多数用户在生产环境中付出性能代价,因为他们将启用 *asserts*

作为库的消费者,由于您不知道哪些库正在使用断言,您必须始终记得在必要时禁用它们。

由于在 Clojure 中全局禁用它们并不容易,因为 assert 是一个检查 *assert* 的宏,需要在该变量加载任何命名空间之前设置其值,所以这种情况变得更糟。

与 Java 相反,Java 默认禁用所有断言,因此库的创建者无需考虑这一点,而消费者可以在开发时分显地启用它们,通过提供 java -ea(启用断言)。

由于我认为改变 *assert* 的默认值可能会由于向后兼容性问题而成为问题,所以可能可以添加一个类似 Rust 的 debug-assert,它不会默认开启。

据我看,关键部分是有一个简单的.Invariant 检查指令,我们知道它默认不会影响性能,所以强化我们的测试和开发代码库不会在默认情况下与生产性能耦合。

其他两个选项是更好的 assert 默认值,一个是 false,另一个是 java.lang.Class desiredAssertionStatus() 的值,它似乎根据是否提供了 -ea 标志返回 true/false,这也会默认为 false。但由于大多数 Clojure 用户已经依赖于 assert 默认为 true,这也许不是一个选项。

by
我认为添加.debug-assert此类功能对库开发者来说非常有益,可以在测试时选择启用(且库用户也可以选择在测试时启用),而应用程序开发者则可以选择使用.assert或选择不启用它们,以便在生产环境中不激活它们。
by
编辑 by
支持`debug-assert`。我相信绝对需要有一种通用的、可靠的方式,可以将断言添加到库中,确保它们在任何情况下都不会默认出现在任何人的生产构建中,除非用户明确选择启用。

有些检查在开发和测试期间是显然可取的,但默认放入生产环境中却过于昂贵,其他一些在生产环境中可能是必要的,以避免潜在的数据损坏和复杂的传播失败。

库作者应该有能力选择在哪里划这条线,这不应该是一个全有或全无的选择,作者在开发和测试期间不应被限制在检验程度,因为他们必须担心可能会将过于极端、成本过高的检查转嫁给下游的消费者。

当然,对于应用开发者来说,区分仅限dev/test的断言和生产断言也非常有用。

附加说明。Clojurians Slack上的讨论线程
https://app.slack.com/client/T03RZGPFR/C03S1KBA2

编辑

我建议将标题更改为类似于“将`debug-assert`作为独立、默认不启用的操作添加,用于昂贵的开发和测试断言”来明确这里提出的建议。
by
我将添加https://docs.clojure.org/clojure.spec.alpha/assert到讨论中,因为它是默认不启用的(在运行时,但在运行时可以打开以进行测试,也可以在编译时完全禁用)。

推荐将这种方式作为库的方法的唯一问题是,由于没有自定义消息选项,您将处于Spec失败的 mercy( mercy是网路用语,意指“运气”)之中,就像常规assert一样。
by
如果我的理解正确,您将只在dev/test时使用debug-assert以进行断言。然后,您将使用常规assert在生产环境中需要的断言。

这开始让我觉得有点像记录日志了。我们能否为当前的assert函数添加类似于日志级别的“级别”?
by
我提议debug-assert只是为了不破坏assert的向后兼容性。我认为当前的assert不适合用于任何与生产相关的内容,因为它们可以被禁用。我认为我们应该使用我们的正常(when-not something (throw ...))来检查我们代码中的重要内容。
debug-assert的整个目的是让它成为java中的assert,一个您可以在dev中“abuse”(abuse是网络用语,意指“滥用”)来检查不变性,但是您肯定不会不小心将其放入生产中,并使您的代码用户支付性能价格。

所以我看不到这里的级别,只是一个开发工具。

登录注册,以回答此问题。

...