2017-10-20 04:57:30 +02:00
|
|
|
# Quotes and Combinators
|
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
RETRO makes extensive use of two elements that need some explanation. These
|
|
|
|
are called quotes and combinators.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
A *quote* is an anonymous function. They are nestable and can be created at
|
|
|
|
any time.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#12 [ dup * ] call
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
In this, the code stating with `[` and ending with `]` is the quote. Here
|
|
|
|
it's just `call`ed immediately, but you can also pass it to other words.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
We use the word *combinator* to refer to words that operate on quotes.
|
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
You'll use quotes and combinators extensively for controlling the flow of
|
|
|
|
execution. This begins with conditionals.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
Assuming that we have a flag on the stack, you can run a quote if the
|
|
|
|
flag is `TRUE`:
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#1 #2 eq?
|
2018-05-07 18:39:49 +02:00
|
|
|
[ 'True! s:put ] if
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
Or if it's `FALSE`:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#1 #2 eq?
|
2018-05-07 18:39:49 +02:00
|
|
|
[ 'Not_true! s:put ] -if
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
There's also a `choose` combinator:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#1 #2 eq?
|
2018-05-07 18:39:49 +02:00
|
|
|
[ 'True! s:put ]
|
|
|
|
[ 'Not_true! s:put ] choose
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
RETRO also uses combinators for loops:
|
|
|
|
|
|
|
|
A counted loop takes a count and a quote:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2018-05-07 18:39:49 +02:00
|
|
|
#0 #100 [ dup n:put sp n:inc ] times
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
You can also loop while a quote returns a flag of `TRUE`:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#0 [ n:inc dup #100 lt? ] while
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
Or while it returns `FALSE`:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
#100 [ n:dec dup n:zero? ] until
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
In RETRO you can also use combinators to iterate over data structures. For
|
|
|
|
instance, many structures provide a `for-each` combinator which can be run
|
|
|
|
once for each item in the structure. E.g., with a string:
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2018-05-07 18:39:49 +02:00
|
|
|
'Hello [ c:put ] s:for-each
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
Moving further, combinators are also used for filters and operations on
|
|
|
|
data. Again with strings:
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
'Hello_World! [ c:-vowel? ] s:filter
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
This runs `s:filter` which takes a quote returning a flag. For each `TRUE`
|
|
|
|
it appends the character into a new string, while `FALSE` results are
|
|
|
|
discarded.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
You might also use a `map`ping combinator to update a data set:
|
|
|
|
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
'Hello_World [ c:to-upper ] s:map
|
2018-04-25 18:57:28 +02:00
|
|
|
~~~
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
This takes a quote that modifies a value which is then used to build a
|
|
|
|
new string.
|
2017-10-20 04:57:30 +02:00
|
|
|
|
2017-10-22 20:39:45 +02:00
|
|
|
There are many more combinators. Look in the Glossary to find them. Some
|
|
|
|
notable ones include:
|
2017-10-20 04:57:30 +02:00
|
|
|
|
|
|
|
bi
|
|
|
|
bi*
|
|
|
|
bi@
|
|
|
|
tri
|
|
|
|
tri*
|
|
|
|
tri@
|
|
|
|
dip
|
|
|
|
sip
|