 
 HELP: [|
 { $syntax "[| bindings... | body... ]" }
-{ $description "A lambda abstraction. When called, reads stack values into the bindings from left to right; the body may then refer to these bindings." }
-{ $examples
-    { $example
-        "USING: kernel locals math prettyprint ;"
-        "IN: scratchpad"
-        ":: adder ( n -- quot ) [| m | m n + ] ;"
-        "3 5 adder call ."
-        "8"
-    }
-} ;
+{ $description "A literal quotation with named variable bindings. When the quotation is " { $link call } "ed, it will take values off the datastack values and place them into the bindings from left to right. The body may then refer to these bindings. The quotation may also bind to named variables in an enclosing scope to create a closure." }
+{ $examples "See " { $link "locals-examples" } "." } ;
 
 HELP: [let
-{ $syntax "[let | binding1 [ value1... ]\n       binding2 [ value2... ]\n       ... |\n    body... ]" }
-{ $description "Introduces a set of lexical bindings and evaluates the body. The values are evaluated in parallel, and may not refer to other bindings within the same " { $link POSTPONE: [let } " form; for Lisp programmers, this means that " { $link POSTPONE: [let } " is equivalent to the Lisp " { $snippet "let" } ", not " { $snippet "let*" } "." }
-{ $examples
-    { $example
-        "USING: kernel locals math math.functions prettyprint sequences ;"
-        "IN: scratchpad"
-        ":: frobnicate ( n seq -- newseq )"
-        "    [let | n' [ n 6 * ] |"
-        "        seq [ n' gcd nip ] map ] ;"
-        "6 { 36 14 } frobnicate ."
-        "{ 36 2 }"
-    }
-} ;
+{ $syntax "[let | var-1 [ value-1... ]\n        var-2 [ value-2... ]\n        ... |\n    body... ]" }
+{ $description "Evaluates each " { $snippet "value-n" } " form and binds its result to a new local variable named " { $snippet "var-n" } " lexically scoped to the " { $snippet "body" } ", then evaluates " { $snippet "body" } ". The " { $snippet "value-n" } " forms are evaluated in parallel, so a " { $snippet "value-n" } " form may not refer to previous " { $snippet "var-n" } " definitions inside the same " { $link POSTPONE: [let } " form, unlike " { $link POSTPONE: [let* } "." }
+{ $examples "See " { $link "locals-examples" } "." } ;
 
 HELP: [let*
-{ $syntax "[let* | binding1 [ value1... ]\n        binding2 [ value2... ]\n        ... |\n    body... ]" }
-{ $description "Introduces a set of lexical bindings and evaluates the body. The values are evaluated sequentially, and may refer to previous bindings from the same " { $link POSTPONE: [let* } " form; for Lisp programmers, this means that " { $link POSTPONE: [let* } " is equivalent to the Lisp " { $snippet "let*" } ", not " { $snippet "let" } "." }
-{ $examples
-    { $example
-        "USING: kernel locals math math.functions prettyprint sequences ;"
-        "IN: scratchpad"
-        ":: frobnicate ( n seq -- newseq )"
-        "    [let* | a [ n 3 + ]"
-        "            b [ a 4 * ] |"
-        "        seq [ b / ] map ] ;"
-        "1 { 32 48 } frobnicate ."
-        "{ 2 3 }"
-    }
-} ;
+{ $syntax "[let* | var-1 [ value-1... ]\n        var-2 [ value-2... ]\n        ... |\n    body... ]" }
+{ $description "Evaluates each " { $snippet "value-n" } " form and binds its result to a new local variable named " { $snippet "var-n" } " lexically scoped to the " { $snippet "body" } ", then evaluates " { $snippet "body" } ". The " { $snippet "value-n" } " forms are evaluated sequentially, so a " { $snippet "value-n" } " form may refer to previous " { $snippet "var-n" } " definitions inside the same " { $link POSTPONE: [let* } " form." }
+{ $examples "See " { $link "locals-examples" } "." } ;
 
 { POSTPONE: [let POSTPONE: [let* } related-words
 
 HELP: [wlet
 { $syntax "[wlet | binding1 [ body1... ]\n        binding2 [ body2... ]\n        ... |\n     body... ]" }
-{ $description "Introduces a set of lexically-scoped non-recursive local functions. The bodies may not refer to other bindings within the same " { $link POSTPONE: [wlet } " form; for Lisp programmers, this means that Factor's " { $link POSTPONE: [wlet } " is equivalent to the Lisp " { $snippet "flet" } ", not " { $snippet "labels" } "." }
+{ $description "Introduces a set of lexically-scoped non-recursive local functions. The bodies may not refer to other bindings within the same " { $link POSTPONE: [wlet } " form." }
 { $examples
     { $example
         "USING: locals math prettyprint sequences ;"

} ;

HELP: :>
{ $syntax ":> binding" }
{ $description "Introduces a new binding, lexically scoped to the enclosing quotation or definition." }
{ $notes
    "This word can only be used inside a lambda word, lambda quotation or let binding form."
    $nl
    "Lambda and let forms are really just syntax sugar for " { $link POSTPONE: :> } "."
    $nl
    "Lambdas desugar as follows:"
    { $code
        "[| a b | a b + b / ]"
        "[ :> b :> a a b + b / ]"
    }
    "Let forms desugar as follows:"
    { $code
        "[|let | x [ 10 random ] | { x x } ]"
        "10 random :> x { x x }"
    }
}
{ $examples
    { $code
        "USING: locals math kernel ;"
        "IN: scratchpad"
        ":: quadratic ( a b c -- x y )"
        "    b sq 4 a c * * - sqrt :> disc"
        "    b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;"
    }
} ;

HELP: ::
{ $syntax ":: word ( bindings... -- outputs... ) body... ;" }
{ $description "Defines a word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." }
{ $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." }
{ $examples "See " { $link POSTPONE: [| } ", " { $link POSTPONE: [let } " and " { $link POSTPONE: [wlet } "." } ;

{ POSTPONE: : POSTPONE: :: } related-words

HELP: MACRO::
{ $syntax "MACRO:: word ( bindings... -- outputs... ) body... ;" }
{ $description "Defines a macro with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." }
{ $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." } ;

{ POSTPONE: MACRO: POSTPONE: MACRO:: } related-words

HELP: MEMO::
{ $syntax "MEMO:: word ( bindings... -- outputs... ) body... ;" }
{ $description "Defines a memoized word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." } ;

{ POSTPONE: MEMO: POSTPONE: MEMO:: } related-words
                                          
HELP: M::
{ $syntax "M:: class generic ( bindings... -- outputs... ) body... ;" }
{ $description "Defines a method with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." }
{ $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." } ;

{ POSTPONE: M: POSTPONE: M:: } related-words

                                                 
ARTICLE: "locals-literals" "Locals in literals"
"Certain data type literals are permitted to contain free variables. Any such literals are written into code which constructs an instance of the type with the free variable values spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables."
$nl
"The data types which receive this special handling are the following:"
{ $list

    "        { [ a 0 = ] [ ... ] }"
    "    } cond ;"
}
"The next two snippets will not compile, because the argument to " { $link cond } " does not immediately precede the call to " { $link cond } ":"
{ $code
    ": my-cond ( alist -- ) cond ; inline"
    ""
