Lexical variables in literals
Factor handbook » The language » Lexical variables

Next:Mutable lexical variables

Certain data type literals are permitted to contain lexical variables. Any such literals are rewritten into code which constructs an instance of the type with the values of the variables spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables.

The data types which receive this special handling are the following:

Object identity
This feature changes the semantics of literal object identity. An ordinary word containing a literal pushes the same literal on the stack every time it is invoked:
USING: kernel ; IN: scratchpad TUPLE: person first-name last-name ; : ordinary-word-test ( -- tuple ) T{ person { first-name "Alan" } { last-name "Kay" } } ; ordinary-word-test ordinary-word-test eq?
--- Data stack: t

Inside a lexical scope, literals which do not contain lexical variables still behave in the same way:
USING: kernel locals ; IN: scratchpad TUPLE: person first-name last-name ; :: locals-word-test ( -- tuple ) T{ person { first-name "Alan" } { last-name "Kay" } } ; locals-word-test locals-word-test eq?
--- Data stack: t

However, literals with lexical variables in them actually construct a new object:
USING: locals kernel splitting ; IN: scratchpad TUPLE: person first-name last-name ; :: constructor-test ( -- tuple ) "Jane Smith" " " split1 :> last :> first T{ person { first-name first } { last-name last } } ; constructor-test constructor-test eq?
--- Data stack: f

One exception to the above rule is that array instances containing free lexical variables (that is, immutable lexical variables not referenced in a closure) do retain identity. This allows macros such as cond to expand at compile time even when their arguments reference variables.