Chapter 5

Tables and text

Lists keep things in order. Tables keep things by name. And text, which you have been writing since chapter 1, has words of its own.

The subject goes on top

One rule decides the order of operands for every word in Ether: the thing a word works on, its subject, is on top of the values stack, and anything else it needs is below. You have seen it already:

programsubject (on top)below it
# 3 # 10 -103, the amount to take away
x { a b } pushthe listthe value to push
# 10 x less-thanx10, what x is compared with

Tables and text work the same way, so when you are unsure of an order, ask which value the word is about, and put that one last.

Tables

A table maps keys to values. Like lists, tables come frozen and thawed: array makes an empty frozen table and tree an empty thawed one. An entry goes in as a pair, which pair makes from a value and a key, value first:

# 3 \ apples pair
values: ( ( "apples" 3 ) )

set takes a pair and a table and gives back the table with the entry. get takes a key and a table and gives back the value. has asks whether the key is there.

tree # 3 \ apples pair swap set
dup \ apples swap get debug
dup \ figs swap has debug
3
false
values: ( { "apples":3 } )

table makes a frozen table from a list of pairs, which is the quickest way to write one down:

[ # 3 \ apples pair # 5 \ pears pair ] table = prices
\ pears prices get debug
prices keys
5
values: ( ( "apples" "pears" ) )

Asking get for a key that is not there is an error, so use has first when you are not sure. keys lists the keys, in no particular order; sort puts a list in order. remove takes a key and a table and gives back the table without it.

A thawed table changes in place, like a stack, so a table bound to a name can collect entries as a program runs. The del drops the table set gives back, since counts already refers to it:

tree = counts
# 1 \ red pair counts set del
# 2 \ blue pair counts set del
counts
values: ( { "blue":2 "red":1 } )

Text

Text in Ether is a block of bytes; every word your program is made of is one. size counts the bytes, words splits text at spaces, and equals compares two texts.

" hello world " dup size debug words
11
values: ( ( "hello" "world" ) )

split and join take the separator below and the text or list on top. Inside quotes, \s keeps a space that would otherwise be dropped:

" , " " a,b,c " split debug
" , \s " [ \ a \ b \ c ] join debug
( "a" "b" "c" )
a, b, c
values: ( )

string turns anything into text, and integer reads a number from text. rom joins a list of texts into one:

[ # 7 string " \s apples " ] rom debug
" 42 " integer ++ debug
7 apples
43
values: ( )

Exercise 5.1

Make a table of prices with apples at 3 and pears at 5, and print the price of pears.

A correct answer prints:

5
values: ( )
One answer
[ # 3 \ apples pair # 5 \ pears pair ] table \ pears swap get debug
5
values: ( )

Exercise 5.2

Count how many times each word appears in the cat and the hat, and print the count for the.

A correct answer prints:

2
values: ( )
One answer
tree = counts
" the cat and the hat " words
{ dup counts has
  { dup counts get ++ swap pair counts set del }
  { # 1 swap pair counts set del }
  either } foreach
\ the counts get debug
2
values: ( )

Exercise 5.3

Print the words of to be or not in reverse order, separated by single spaces.

A correct answer prints:

not or be to
values: ( )
One answer
" \s " " to be or not " words reversed join debug
not or be to
values: ( )

Exercise 5.4

Bind n to 12 and print the text 12 eggs built from it.

A correct answer prints:

12 eggs
values: ( )
One answer
# 12 = n
[ n string " \s eggs " ] rom debug
12 eggs
values: ( )