Clojure

Add some?, when-some, if-some for (not (nil? x)) conditions

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: Release 1.5
  • Fix Version/s: Release 1.6
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test
  • Approval:
    Ok

Description

Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

  • some? - same as (not (nil? x))
  • if-some - like if-let, but checks (some? test) instead of test
  • when-some - like when-let, but checks (some? test) instead of test

Patch: clj-1343-4.patch

  1. clj-1343-1.patch
    07/Feb/14 11:21 AM
    3 kB
    Alex Miller
  2. clj-1343-2.patch
    12/Feb/14 12:38 PM
    4 kB
    Alex Miller
  3. clj-1343-3.patch
    14/Feb/14 10:01 AM
    4 kB
    Alex Miller
  4. clj-1343-4.patch
    14/Feb/14 10:39 AM
    4 kB
    Alex Miller

Activity

Alex Miller made changes -
Field Original Value New Value
Approval Vetted [ 10003 ]
Attachment clj-1343-1.patch [ 12768 ]
Fix Version/s Release 1.6 [ 10157 ]
Stuart Halloway made changes -
Resolution Completed [ 1 ]
Status Open [ 1 ] Closed [ 6 ]
Hide
Alex Miller added a comment -

oops

Show
Alex Miller added a comment - oops
Alex Miller made changes -
Approval Vetted [ 10003 ] Screened [ 10004 ]
Status Closed [ 6 ] Reopened [ 4 ]
Resolution Completed [ 1 ]
Hide
Tassilo Horn added a comment -

At least to me, the name `some?` doesn't convey the same information as "not nil", so I'd rather prefer a more explicit name like `non-nil?`.

Also, I'm not convinced of the benefit of something like `(when-some x ...)` compared to `(when-not (nil? x) ...)`. A little shorter and one pair of parens less, but IMHO not as clear.

Show
Tassilo Horn added a comment - At least to me, the name `some?` doesn't convey the same information as "not nil", so I'd rather prefer a more explicit name like `non-nil?`. Also, I'm not convinced of the benefit of something like `(when-some x ...)` compared to `(when-not (nil? x) ...)`. A little shorter and one pair of parens less, but IMHO not as clear.
Hide
Jozef Wagner added a comment -

In my opinion, some? should be defined as (not (empty? coll)), and used as in "are there 'some' items in this collection?". This will also play nicely with some, which also takes collection as an argument.

Show
Jozef Wagner added a comment - In my opinion, some? should be defined as (not (empty? coll)), and used as in "are there 'some' items in this collection?". This will also play nicely with some, which also takes collection as an argument.
Hide
Tassilo Horn added a comment -

Jozef, for that purpose, you'd use `seq`. Actually, the definition of `empty?` is `(not (seq coll))`, so your suggestion would boil down to `some?` being `(not (not (seq coll)))`.

Show
Tassilo Horn added a comment - Jozef, for that purpose, you'd use `seq`. Actually, the definition of `empty?` is `(not (seq coll))`, so your suggestion would boil down to `some?` being `(not (not (seq coll)))`.
Hide
Rich Hickey added a comment -

if-some and when-some are supposed to be like if-let and when-let respectively. Changelog will need updating as well

Show
Rich Hickey added a comment - if-some and when-some are supposed to be like if-let and when-let respectively. Changelog will need updating as well
Rich Hickey made changes -
Approval Screened [ 10004 ] Incomplete [ 10006 ]
Hide
Alex Miller added a comment -

Updated patch to make if-some and when-some similar to if-let and when-let.

Show
Alex Miller added a comment - Updated patch to make if-some and when-some similar to if-let and when-let.
Alex Miller made changes -
Approval Incomplete [ 10006 ] Vetted [ 10003 ]
Description Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - same as (if (some? test) then else)
* when-some - same as (when (some? test) body)
Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - like if-let, but checks (some? test) instead of test
* when-some - like when-let, but checks (some? test) instead of test

*Patch:* clj-1343-2.patch
Attachment clj-1343-2.patch [ 12784 ]
Stuart Halloway made changes -
Approval Vetted [ 10003 ] Screened [ 10004 ]
Hide
Alex Miller added a comment -

New patch that does not use "some?" in if-some and when-some.

Show
Alex Miller added a comment - New patch that does not use "some?" in if-some and when-some.
Alex Miller made changes -
Attachment clj-1343-3.patch [ 12789 ]
Alex Miller made changes -
Description Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - like if-let, but checks (some? test) instead of test
* when-some - like when-let, but checks (some? test) instead of test

*Patch:* clj-1343-2.patch
Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - like if-let, but checks (some? test) instead of test
* when-some - like when-let, but checks (some? test) instead of test

*Patch:* clj-1343-3.patch
Rich Hickey made changes -
Approval Screened [ 10004 ] Incomplete [ 10006 ]
Stuart Halloway made changes -
Approval Incomplete [ 10006 ] Screened [ 10004 ]
Rich Hickey made changes -
Approval Screened [ 10004 ] Incomplete [ 10006 ]
Hide
Alex Miller added a comment -

New patch that adjusts when-some impl.

Show
Alex Miller added a comment - New patch that adjusts when-some impl.
Alex Miller made changes -
Approval Incomplete [ 10006 ] Vetted [ 10003 ]
Description Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - like if-let, but checks (some? test) instead of test
* when-some - like when-let, but checks (some? test) instead of test

*Patch:* clj-1343-3.patch
Sometimes it is useful to have a form for non-nil conditions (as opposed to the existing logical true conditions).
Three additions to support this case:

* some? - same as (not (nil? x))
* if-some - like if-let, but checks (some? test) instead of test
* when-some - like when-let, but checks (some? test) instead of test

*Patch:* clj-1343-4.patch
Attachment clj-1343-4.patch [ 12790 ]
Rich Hickey made changes -
Approval Vetted [ 10003 ] Ok [ 10007 ]
Stuart Halloway made changes -
Resolution Completed [ 1 ]
Status Reopened [ 4 ] Closed [ 6 ]
Hide
Kyle Kingsbury added a comment -

I'd like to echo Jozef Wagner's and Steve Losh's confusion here.

```
user=> (some odd? [1 2 3])
true
user=> (some? odd? [1 2 3])

ArityException Wrong number of args (2) passed to: user$some-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
```

I might expect (some?) to behave like (some), except returning a boolean instead of a logically true value, but this is clearly not the case. In no other case in the stdlib can I think of two functions which differ only by punctuation yet have completely different semantics.

```
user=> (some? [])
true
```

Given (some)'s association with sequences, I might interpret (some?) to mean "are there some elements here?"; but that's definitely wrong. Given we have (not=), (not-any?), (not-empty), and (not-every?), can we please name this function (not-nil?)? It's only three characters, but makes the interpretation unambiguously clear.

```
user=> (def x nil)
#'user/x
user=> (def y nil)
#'user/y
user=> (some? [x y])
true
user=> (when-some [x y] :i-expect-true)
nil
```

The fact that (when-some) and (if-some) behave like let bindings is, erm, quite surprising to me. The other binding conditionals have -let in their name; perhaps it would be appropriate to use -let here as well?

For that matter, is this use case all that common? I think I reach specifically for a nil? test fewer than 1 in 20 conditionals--in those cases, why not just write

```
(when-let [x (not-nil? y)]
...)
```

instead of

```
(when-some [x y]
...)
```

I'm just not convinced that this pattern is common enough to warrant the confusion of (when-some) having nothing to do with (when (some ...)), haha. What do y'all think? Have I missed some symmetry between (some?) and (some) that helps this all make sense?

Show
Kyle Kingsbury added a comment - I'd like to echo Jozef Wagner's and Steve Losh's confusion here. ``` user=> (some odd? [1 2 3]) true user=> (some? odd? [1 2 3]) ArityException Wrong number of args (2) passed to: user$some-QMARK- clojure.lang.AFn.throwArity (AFn.java:437) ``` I might expect (some?) to behave like (some), except returning a boolean instead of a logically true value, but this is clearly not the case. In no other case in the stdlib can I think of two functions which differ only by punctuation yet have completely different semantics. ``` user=> (some? []) true ``` Given (some)'s association with sequences, I might interpret (some?) to mean "are there some elements here?"; but that's definitely wrong. Given we have (not=), (not-any?), (not-empty), and (not-every?), can we please name this function (not-nil?)? It's only three characters, but makes the interpretation unambiguously clear. ``` user=> (def x nil) #'user/x user=> (def y nil) #'user/y user=> (some? [x y]) true user=> (when-some [x y] :i-expect-true) nil ``` The fact that (when-some) and (if-some) behave like let bindings is, erm, quite surprising to me. The other binding conditionals have -let in their name; perhaps it would be appropriate to use -let here as well? For that matter, is this use case all that common? I think I reach specifically for a nil? test fewer than 1 in 20 conditionals--in those cases, why not just write ``` (when-let [x (not-nil? y)] ...) ``` instead of ``` (when-some [x y] ...) ``` I'm just not convinced that this pattern is common enough to warrant the confusion of (when-some) having nothing to do with (when (some ...)), haha. What do y'all think? Have I missed some symmetry between (some?) and (some) that helps this all make sense?
Hide
Alex Miller added a comment -

Summarizing comments here, mailing list, Twitter, etc:

  • some uses a truthy comparison. some->, some->> use a not nil comparison. This difference existed in 1.5 some?/if-some/when-some follow the latter. This split is unfortunate, but existed before this addition.
  • not-nil?, non-nil?, nnil?, exists?, and all other alternatives I've seen mentioned were considered as options before the existing names were chosen by Rich. Many people have expressed negative feedback about the name choices and I will channel that to Rich for consideration, but ultimately the choice is his.
  • if-some and when-some are likely more useful than some?. In particular, it is commonly needed when reading from core.async channels where nil is a special value (but false is not).
(go
  (if-some [v (<! c)]
    ...))
Show
Alex Miller added a comment - Summarizing comments here, mailing list, Twitter, etc:
  • some uses a truthy comparison. some->, some->> use a not nil comparison. This difference existed in 1.5 some?/if-some/when-some follow the latter. This split is unfortunate, but existed before this addition.
  • not-nil?, non-nil?, nnil?, exists?, and all other alternatives I've seen mentioned were considered as options before the existing names were chosen by Rich. Many people have expressed negative feedback about the name choices and I will channel that to Rich for consideration, but ultimately the choice is his.
  • if-some and when-some are likely more useful than some?. In particular, it is commonly needed when reading from core.async channels where nil is a special value (but false is not).
(go
  (if-some [v (<! c)]
    ...))

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: