7. defining symbols
Another element of code in alv
that we haven’t discussed in detail yet are
symbols. Symbols (like trace
, import*
or math/+
) are names that serve
as placeholders for previously defined values. When code is evaluated, symbols
are looked up in the current scope and replaced with the corresponding value
found there.
When an alv
file starts running, a number of symbols are defined in the
default scope: These are the builtins mentioned above, and of which we have
already been using trace
, import
, and import*
.
To define a symbol yourself, the def
builtin is used. It takes the symbol
as its first, and the value to associate as its second parameter. After a symbol
is defined, the name becomes an alias that behaves like the value itself. For
example, we can use def
to associate the result of our calculation with the
symbol result
, and then refer to it by that symbol in the trace
operator:
(import* math)
(def result (+ 1 2))
(trace result)
Symbols need to start with a letter or one of the following special characters:
- + * /
_ . , =
! ? % $
> < ~
After the first character, numbers are also allowed. There are two types of
symbols that are treated specially: symbols containing a slash (math/+
), and
symbols starting and ending with asterisks (*clock*
):
- Symbols containing slashes (except at beginning and end of the symbol) are
split into multiple symbols, and looked up recursively in the scope. For
example,
math/+
is found by first looking for a value for the symbolmath
, and then looking for the symbol+
in that value. If the value for the symbolmath
is not a scope, an error is thrown. - Symbols starting and ending with asterisks are called dynamic symbols and are looked up in a different way inside user-defined functions. This will be covered in detail later.
- The two special formats can be mixed: when evaluating
*hello*/world
,alv
will look for the symbolworld
within the scope found by dynamically resolving*hello*
.