Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why prefer seq over non-empty as a predicate?

Tags:

clojure

The docstring for empty? says "Please use the idiom (seq x) rather than (not (empty? x))". MisterMetaphor points out that using seq as a predicate can make sense when used in if-let:

(if-let [s (seq might-be-empty)]
   (fn-for-non-empty-seq s)
   (fn-for-empty-seq))

Should I really use seq to test for non-emptiness in general, though? seq may convert its argument to a different form. For example:

user=> (class (lazy-seq '(1 2 3)))
clojure.lang.LazySeq
user=> (class (seq (lazy-seq '(1 2 3))))
clojure.lang.PersistentList
user=> (class (map inc [1 2 3]))
clojure.lang.LazySeq
user=> (class (seq (map inc [1 2 3])))
clojure.lang.ChunkedCons

That seems like a waste of cycles if just want to test for non-emptiness, and don't need a new binding, or if I don't need the conversion before the binding. Wouldn't not-empty be a better choice in such cases? It returns nil if its argument is empty, and its argument unchanged if non-empty.

(if (not-empty [])
  "more to do"
  "all done")
like image 547
Mars Avatar asked Feb 06 '14 05:02

Mars


People also ask

What is a predicate?

(with Examples) The predicate is the part of a sentence (or clause) that tells us what the subject does or is. To put it another way, the predicate is everything that is not the subject. At the heart of the predicate is a verb. In addition to the verb, a predicate can contain direct objects, indirect objects, and various kinds of phrases.

What is a predicate nominative?

A predicate nominative can be made up of more than one noun. In other words, it can be a compound predicate nominative. Your proposal was an opportunity and a risk. ("An opportunity and a risk" is a compound predicate nominative.) I will be your employer, your advisor and your friend.

What is the verb at the heart of every predicate?

At the heart of every predicate is a verb. In each example below, the verb in the predicate is shown in bold. True friends appear less moved than counterfeit. (Greek philosopher Homer)

Which sentence is not an example of a compound predicate?

They need to absorb nitrogen and keep above 20 degrees. Remember that a compound predicate tells us at least two things about one subject. So, the following sentence is not an example of a compound predicate: Rachel lives in Dublin, and she speaks Irish. (This is a compound sentence. It has two subjects ("Rachel" and "she").


1 Answers

First, check out the definition of empty?:

(defn empty?
  "Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))"
  {:added "1.0"
  :static true}
  [coll] (not (seq coll)))

So empty? is (not (seq coll)). That's why it's discouraged to complement empty?, because you are doing a double negation on seq.

Now see not-empty

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

Surprise, it uses seq as the test of non-emptiness too. This not-empty is useful if the type matters -- nth performance on vectors, conj behavior, etc. -- because it does return non-empty colls as is. Used as just a predicate though, it would only be wrapping seq.

Don't worry about seq being heavy-handed though. It does little more than return an iterator. It does not actually convert the entire data structure.

like image 178
A. Webb Avatar answered Oct 22 '22 02:10

A. Webb