A let form creates local names for evaluated expressions within a lexical scope. Each bound expression is evaluated once, and the resulting name can be reused without re-evaluation. The bindings are immutable; a later binding may shadow an earlier one without mutating it. section 3.1 section 3.1.1
Use the following contract to read and construct a let form:
- Write a possibly empty vector containing an even number of elements: binding expression, value expression, and so on. section 3.1.1
- Place valid binding expressions at even indexes; destructuring is allowed. section 3.1.1
- Treat the remaining expressions as the body; multiple body expressions are implicitly wrapped in do. section 3.1.1
- Return the last body expression, or nil when the body is empty. section 3.1.1
- Avoid primitive type hints on local bindings such as ^long i; let recognizes primitive locals and rejects this hint with UnsupportedOperationException. section 3.1.1
Bind a random result once
(let [x (rand-int 10)] (if (>= x 5) (str x " is above the average") (str x " is below the average"))) Here, both branches use the same value of x rather than evaluating rand-int again. section 3.1.1
let and let*
let is the user-facing macro. let* is the special form that let uses internally to parse and validate its bindings, so direct use of let* normally offers no specific benefit. A let form is closely equivalent to invoking an anonymous function with the bound values as parameters. section 3.1.1 section 3.1
