在Clojure中是否有除nil-punning以外的惯用替代方法? [英] Is there an idiomatic alternative to nil-punning in Clojure?

查看:120
本文介绍了在Clojure中是否有除nil-punning以外的惯用替代方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在读取一些Clojure代码,该代码具有大量未初始化的值,例如nil,用于传递到记录中的数字值.

I'm reading some Clojure code at the moment that has a bunch of uninitialised values as nil for a numeric value in a record that gets passed around.

现在很多Clojure库

Now lots of the Clojure libraries treat this as idiomatic. Which means that it is an accepted convention.

但是它也会导致NullPointerException,因为并非所有Clojure核心函数都可以将nil作为输入处理. (他们也不应该).

But it also leads to NullPointerException, because not all the Clojure core functions can handle a nil as input. (Nor should they).

其他语言具有MaybeOption的概念,以在值为null的情况下代替该值,以减轻NullPointerException风险.这在Clojure中是可能的-但不能很常见.

Other languages have the concept of Maybe or Option to proxy the value in the event that it is null, as a way of mitigating the NullPointerException risk. This is possible in Clojure - but not very common.

您可以使用fnil做一些技巧,但这不能解决所有问题.

You can do some tricks with fnil but it doesn't solve every problem.

另一种选择是简单地将未初始化的值设置为类似:empty-value的符号,以强制用户在所有处理代码中显式处理此方案.但这并不是nil的真正提升,因为您直到运行时才真正发现所有场景(用他人的代码).

Another alternative is simply to set the uninitialised value to a symbol like :empty-value to force the user to handle this scenario explicitly in all the handling code. But this isn't really a big step-up from nil - because you don't really discover all the scenarios (in other people's code) until run-time.

我的问题是:在Clojure中是否有除nil-punning以外的惯用替代方法?

推荐答案

不确定您是否已阅读过Lispcast nil-punning上的> post ,但我确实认为这是为什么它很惯用的一个很好的例子,并涵盖了我在其他SO问题中没有提到的各种重要考虑因素.

Not sure if you've read this lispcast post on nil-punning, but I do think it makes a pretty good case for why it's idiomatic and covers various important considerations that I didn't see mentioned in those other SO questions.

基本上,nil是Clojure中的头等物品.尽管具有固有的常规含义,它还是一个适当的值,并且可以在许多上下文中以上下文相关的方式处理.与宿主语言中的null相比,它更加灵活和强大.

Basically, nil is a first-class thing in clojure. Despite its inherent conventional meaning, it is a proper value, and can be treated as such in many contexts, and in a context-dependent way. This makes it more flexible and powerful than null in the host language.

例如,类似的东西甚至无法在java中编译:

For example, something like this won't even compile in java:

if(null) {
....
}

与clojure一样,(if nil ...)也可以正常工作.因此,在许多情况下,您可以安全地使用 nil.我还没有看到一个随处可见if(foo != null) { ...之类的代码的Java代码库.也许Java 8的Optional会改变这一点.

Where as in clojure, (if nil ...) will work just fine. So there are many situations where you can use nil safely. I'm yet to see a java codebase that isn't littered with code like if(foo != null) { ... everywhere. Perhaps java 8's Optional will change this.

我认为您可以容易遇到问题的地方是在Java interop场景中,您正在处理实际的null s.一个好的clojure包装器库在很多情况下也可以帮助您避免这种情况,这是在可能的情况下优于直接Java互操作的一个好理由.

I think where you can run into issues quite easily is in java interop scenarios where you are dealing with actual nulls. A good clojure wrapper library can also help shield you from this in many cases, and its one good reason to prefer one over direct java interop where possible.

鉴于此,您可能需要重新考虑与当前潮流作斗争.但是由于您正在询问替代方案,因此我认为这很棒:棱镜的模式.模式具有Maybe模式(以及许多其他有用的模式),并且在许多情况下都可以很好地工作.该图书馆非常受欢迎,我已经成功地使用了它. FWIW,建议在最近的 clojure应用书中.

In light of this, you may want to re-consider fighting this current. But since you are asking about alternatives, here's one I think is great: prismatic's schema. Schema has a Maybe schema (and many other useful ones as well), and it works quite nicely in many scenarios. The library is quite popular and I have used it with success. FWIW, it is recommended in the recent clojure applied book.

这篇关于在Clojure中是否有除nil-punning以外的惯用替代方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆