not-empty には ? が付かない

理由は単純。評価結果が 真/偽じゃないから。

(empty? [])    ;=> true
(empty? [1 2]) ;=> false

(not-empty [])    ;=> nil
(not-empty [1 2]) ;=> [1 2]

not-empty の実装を見ると

(defn not-empty
  "If coll is empty, returns nil, else coll"
  {:added "1.0"}
  [coll] (when (seq coll) coll))

さらに、seq の実装をみると

(def
 ^{:arglists '([coll])
   :doc "Returns a seq on the collection. If the collection is
    empty, returns nil.  (seq nil) returns nil. seq also works on
    Strings, native Java arrays (of reference types) and any objects
    that implement Iterable."
   :tag clojure.lang.ISeq
   :added "1.0"}
 seq (fn seq [coll] (. clojure.lang.RT (seq coll))))

説明がズラズラと書かれてますが、ここでのポイントは「コレクションが空の時 nil を返す」ってところ。not-empty はこの seq の特性と、nil が 偽 と判定される仕様を使って実装されているわけですね。*1

ところで、何故

(defn not-empty
  [coll] (seq coll))

じゃなく

(defn not-empty
  [coll] (when (seq coll) coll))

なんだろう?
違いは、Persistent なコレクションを渡したとき返却値が、引数そのものか seq かという点。
not-empty に関して言うならばどちらでもよさそうな気がするけど、わざわざ collection で返さなければならない理由があるんだろうか?

#無限シーケンスで使うとき注意

empty? は無限シーケンスでも特に問題ないけど

(empty? (range)) ;=> false


not-empty は空でないとき引数をそのまま返すので注意が必要

(not-empty (range)) ;=> 無限シーケンス

うっかり正格評価すると帰ってきません。

#やっぱり not-empty? も欲しいかも(?)

簡単に作れるけど ....

(defn not-empty?
  [coll] (not (empty? coll)))

(not-empty? [])      ;=> false
(not-empty? [1 2])   ;=> true
(not-empty? (range)) ;=> true

うーん、これだったら作るまでもないか。

*1:Pythonista は注意が必要。空っぽのコレクションは clojure では偽にならない。また、Lisper も注意 (= '() nil) => false です。