Constants
Tuesday, October 29, 2024
Factor has programmable syntax, a feature that allows for concise source code, reducing repetition and allowing the programmer to express forms and intent with minimal tokens. As an example of this, today I want to discuss constants.
You can define a word with a constant value, using syntax like this:
CONSTANT: three 3
Someone on our Factor Discord server asked if it was possible to define multiple constants in one syntax expression, to avoid the line noise of defining them one-by-one.
So, instead of these four definitions:
CONSTANT: foo 1
CONSTANT: bar $[ 2 sqrt ]
CONSTANT: baz $ bar
CONSTANT: qux \ foo
We could instead make this syntax:
SYNTAX: CONSTANTS:
";" [
create-word-in
[ reset-generic ]
[ scan-object define-constant ] bi
] each-token ;
Breaking that down into steps:
SYNTAX:
indicates we’re defining new syntaxCONSTANTS:
is the name of our new syntax word";"
defines the terminator that will end our constant definitionseach-token
will process each token until it hits the terminator
For each constant definition, it performs these steps:
create-word-in
creates a new word in the current vocabularyreset-generic
clears any generic word propertiesscan-object
reads and parses the next valuedefine-constant
makes it a constant with the parsed value
And now this expression works, reducing the visual noise in our source code:
CONSTANTS:
foo 1
bar $[ 2 sqrt ]
baz $ bar
qux \ foo
;
As an aside, the different syntaxes used above are:
1
is just a token parsed as a number literal$[ ... ]
evaluates the code inside at parse time$
gets the value of another constant\
gets the word object itself rather than its value
Factor’s syntax parsing words allow a great deal of flexibility in making custom DSL-style syntax forms work nicely to reduce repetition, and generate code with less effort.
I’m not sure if this is worth adding to the standard library or not, but it’s neat!