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

Conditional Binding: if-let and when-let

Pattern-based conditional binding. Bind a value and branch based on whether a pattern matches. Uses the same pattern system as match (Ch 10).

if-let — With an Else Branch

(if-let ((Some user) (find-user id))
  (greet user)
  (redirect-to-login))
{
  const t__gensym0 = findUser(id);
  if (t__gensym0.tag === "Some") {
    const user = t__gensym0.value;
    greet(user);
  } else {
    redirectToLogin();
  }
}

when-let — No Else Branch

(when-let ((Ok data) (fetch-data url))
  (process data))

If the pattern doesn’t match, nothing happens. No else branch, no fallback.

Three Pattern Types

ADT constructor — PascalCase triggers constructor matching:

(if-let ((Some v) (find id))
  (use v)
  (fallback))

Simple binding — lowercase triggers nil check:

(if-let (config (load-config))
  (start-with config)
  (start-default))

This binds config if (load-config) is not null/undefined. PascalCase distinguishes constructors from simple bindings: Some checks .tag, config checks != null.

Structuralobj pattern checks properties:

(if-let ((obj :data d) response)
  (process d)
  (handle-error response))

The Convenience

if-let is a convenience over match for the common pattern of “unwrap or fallback.” For complex multi-way dispatch, use full match. For quick one-pattern checks, if-let reads cleaner.