Chapter 3
Names
So far every program has been one long line of words. This chapter gives things names: values you want to keep, and lists you want to run as new words.
Naming a value
= takes the value on top and binds it to the word that comes
after it. From then on, that word pushes the value.
# 5 = x x debug x x * debug
5 25 values: ( )
Binding the same name again replaces the old value. This is how a program keeps a counter:
# 1 = count count ++ = count count ++ = count count debug
3 values: ( )
++ adds one to the number on top, and -- subtracts
one.
Naming a list: new words
=> binds a list as a word: running the name runs the
list.
{ dup * } => square
# 3 square debug
# 3 square square debug
9 81 values: ( )
Compare the two arrows. With = the name pushes the list; with
=> the name runs it.
{ dup * } = keep
{ dup * } => run
# 4 keep
# 4 run
values: ( 16 ( "dup" "*" ) 4 )
Mixing up the two is a common mistake: a word bound with =
when you meant => pushes its list instead of running it, and
the error comes later, from whichever word receives the list.
A word you define this way is a macro, exactly like the words built into Ether, and the step rule cannot tell them apart. A word can use any word that exists when it runs, including words defined later and itself.
The macro table
macros pushes the macro table, the table the step rule looks
words up in. \ pushes the next word without running it, which is
how you talk about a word instead of using it. Together they answer
"is this word defined?":
\ square macros has debug
{ dup * } => square
\ square macros has debug
false true values: ( )
A word may already be taken. Ether comes with 176 words, and
some have short, ordinary names: one, zero,
null, key, object, words,
table, string. A word you meant as
plain data runs instead if it has a definition:
apple one pear
values: ( "pear" 1 "apple" )
one pushed the number 1. Escape such a word with \
when you mean the word itself: \ one. macros keys
lists every defined word: 176 with the native words, and more when the
language is written in Ether, whose definitions keep private helper words in
the table too.
176 values: ( )
Scope
Names are global: a name bound anywhere is visible everywhere afterwards,
and binding it again changes it for everyone. scope runs a list
and then puts the macro table back as it was, so names made inside it do not
escape.
# 1 = x
{ # 2 = x x debug } scope
x debug
2 1 values: ( )
Exercise 3.1
Define a word square and use it to print 12 × 12.
A correct answer prints:
144 values: ( )
One answer
{ dup * } => square
# 12 square debug
144 values: ( )
Exercise 3.2
Define square, then define cube using
square, and print the cube of 5.
A correct answer prints:
125 values: ( )
One answer
{ dup * } => square
{ dup square * } => cube
# 5 cube debug
125 values: ( )
Exercise 3.3
Bind total to 10, then add 5 to it and subtract 2 from it,
binding the result to total each time, and print
total.
A correct answer prints:
13 values: ( )
One answer
# 10 = total total # 5 + = total # 2 total - = total total debug
13 values: ( )
Exercise 3.4
Bind greeting to the text hello. Then, inside a
scope, bind it to goodbye and print it. After the
scope, print it again.
A correct answer prints:
goodbye hello values: ( )
One answer
" hello " = greeting
{ " goodbye " = greeting greeting debug } scope
greeting debug
goodbye hello values: ( )