Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Equality in Lykn

JavaScript has four equality mechanisms. Lykn uses one.

The Four Mechanisms

Loose equality (==) coerces types before comparing. It is the source of most equality-related bugs and the mechanism that makes "" == false true. The coercion algorithm is seventeen steps long. Nobody has it memorized.

Strict equality (===) does not coerce. Different types are never equal. 5 === "5" is false. This is what you want virtually all the time.

Object.is is like === but handles two edge cases differently: NaN is equal to NaN (unlike ===), and +0 is not equal to -0 (unlike ===). Used when you need mathematically correct value identity.

SameValueZero is what Map, Set, and Array.prototype.includes use internally. Like Object.is but treats +0 and -0 as equal.

Lykn’s Choice

(= 5 "5")              ;; → 5 === "5"       → false
(= 5 5)                ;; → 5 === 5         → true
(= null undefined)     ;; → null === undefined → false

(= a b) compiles to a === b. Always. There is no surface form for loose equality. The entire coercion equality table — the one where transitivity goes to die — is simply inaccessible.

If you need loose equality (rare, but occasionally useful), the escape hatch is explicit:

(js:eq a b)             ;; → a == b          (explicit, greppable)

The == null Exception

There is one place where Lykn’s compiled output contains ==: the nil checks generated by some->, if-let, and when-let. The compiler emits x == null to catch both null and undefined in a single comparison — the only == check that ESLint’s eqeqeq rule explicitly exempts, and the only one that has a legitimate use case.

(some-> user (get :name) (:to-upper-case))

The compiled output includes == null checks at each step of the threading chain. You never write ==; the compiler uses it surgically, in a context where its behavior is well-defined and useful.

Why This Matters

BugAID’s pattern #4 — using == when === was needed — is one of the most prevalent bug patterns in the 105,133-commit dataset. CoffeeScript proved that compiling == to === unconditionally works, and the pattern was so successful that it influenced a generation of linting rules. Lykn follows the same principle: strict equality by default, loose equality only via explicit opt-in.