I finally discovered why Javascript Sets exist!

My first practical takeaway from learning Clojure

I've used Javascript Sets to de-duplicate items in an array for a few years, but I never understood it beyond that. It felt like one of those obscure language features that would never fully make it into my programs...

// My only usage of sets so far
const uniqueTags = Array.from(new Set(tags))

But reading Russ Olsen's Getting Clojure (which is super well written and fun, by the way!), I casually came upon this line:

Since sets are all about membership, the main thing you can do with them is discover if this or that value is in the set.
(Page 32)

And then it dawned on me: Sets are solely a collection of unique values, so there's no better tool for these use cases it specializes in.

Use-case #1: checking if item is in collection

Set.has is faster than Array.includes:

// With Arrays
const singletonTypes = ['home', 'settings']
const isSingleton = singletonTypes.includes(doc._type)

// With Sets - faster
const singletonTypes = new Set(['home', 'settings'])
const isSingleton = singletonTypes.has(doc._type)

Of course, with few items this is negligible. But this could be a performance opportunity when there are hundreds, thousands of items in a set that is being checked multiple times per second, such as the render method of hundreds of a React/Svelte components.

Use-case #2: ensuring collection has no duplicates

This is way easier with sets:

// With arrays, you manually need to check if item isn't already there
if (!singletonTypes.includes('settings')) {
  singletonTypes.push('settings')
}

// With Sets
singletonTypes.add('settings') // if already exists, it'll be skipped

Issues with Sets

  • Set order is according to time of addition and you can't overwrite this behavior
    • Arrays are still the go-to option for tightly ordered lists of values
  • Sets aren't immutable like in Clojure and they aren't as easy to make immutable like Arrays, so be careful of side-effects in seemingly innocent contexts
  • Sets are rare in most real-world JS, so your code may end up more complicated and inaccessible to beginners than needed

So... yeah, I'm not convinced I'll actually use sets, but now I know how it could be useful. I feel slightly more capable with the language 😊

Bonus: sets are a mathematical concept

These come from the mathematical model of sets. That thing we used in school exercises to denote that a given variable was a real number, α ∈ R, is a practical use of sets.

And reading the Wikipedia article on Sets, I discovered where the term "singleton" came from! It's the sole item in a mathematical set. Next time I create a singleton in my content model, I'll definitely think of Sets.

This is my first "real-world" example of how much programming is based on Mathematics, I'm hooked!

Next up is getting a good grip on Map - but that's a challenge for another time.