It’s quite common to want to match things or want to check that some list contains a particular element. There’s a couple ways to do this in Clojure. One is clearly better than the other.

Use =

(= "Antoine" "Antoine") => true

Therefore:

(some (partial = "Antoine") ["Antoine" "Philippe" "Charles"]) => true

Alternatively:

(some #(= "Antoine" %) ["Antoine" "Philippe" "Charles"]) => true

Use sets

A set can be used as a function to determine if something is in it or not – this basically means any set you have also doubles as a predicate function for performing matching! I’d say 90% of my use of sets is for this.

(#{"Antoine"} "Antoine") => "Antoine"
(#{"Antoine"} "Antoinette") => nil

(some #{"needle"} ["haystack" "haystack" "needle" "haystack"]) => "needle"

Why would you use sets over =? Let’s imagine the following:

  1. You want to show off your knowledge of Clojure.
  2. You need to extend your predicate to also match on another element.
  3. If there is a match, you want to know its value, because you’re smart and built your matcher programmatically instead of hardcoding data into your code.

Using sets solves those three problems much better than =:

;; If I want to match on either of my names:
(some #(or (= "Antoine" %) (= "Pierre" %)) ["John" "William" "Rodrigo" "Pierre" "Antoine"])
;; => true

;; With sets
(some #{"Antoine" "Pierre"} ["John" "William" "Rodrigo" "Pierre" "Antoine"])
;; => Pierre

I’m not even going to write out the very verbose way to get the value of the matching element with = (hint, you’ll probably need to use a when statement). Just use sets.

Also:

(count "#(= )") => 5
(count "(#{})") => 5
(count "(partial = )") => 12

Yes, that’s right – using the set notation is exactly as short as using an anonymous function!!! You’re welcome.

If you want to discuss this, comment or troll me, feel free to drop a tweet my way. If this made you happy, you can also follow me for more!