retroforth/doc/QuotesAndCombinators.md
crc ed89e0bde8 rename references to old names in doc
FossilOrigin-Name: 0b0cd20ed69027a7d9b5f2d905d7b9e033e2976208385652d888da35432a4482
2018-05-07 16:39:49 +00:00

2.1 KiB

Quotes and Combinators

RETRO makes extensive use of two elements that need some explanation. These are called quotes and combinators.

A quote is an anonymous function. They are nestable and can be created at any time.

Example:

  #12 [ dup * ] call

In this, the code stating with [ and ending with ] is the quote. Here it's just called immediately, but you can also pass it to other words.

We use the word combinator to refer to words that operate on quotes.

You'll use quotes and combinators extensively for controlling the flow of execution. This begins with conditionals.

Assuming that we have a flag on the stack, you can run a quote if the flag is TRUE:

  #1 #2 eq?
  [ 'True! s:put ] if

Or if it's FALSE:

  #1 #2 eq?
  [ 'Not_true! s:put ] -if

There's also a choose combinator:

  #1 #2 eq?
  [ 'True! s:put     ]
  [ 'Not_true! s:put ] choose

RETRO also uses combinators for loops:

A counted loop takes a count and a quote:

  #0 #100 [ dup n:put sp n:inc ] times

You can also loop while a quote returns a flag of TRUE:

  #0 [ n:inc dup #100 lt? ] while

Or while it returns FALSE:

  #100 [ n:dec dup n:zero? ] until

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:

  'Hello [ c:put ] s:for-each

Moving further, combinators are also used for filters and operations on data. Again with strings:

  'Hello_World! [ c:-vowel? ] s:filter

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.

You might also use a mapping combinator to update a data set:

  'Hello_World [ c:to-upper ] s:map

This takes a quote that modifies a value which is then used to build a new string.

There are many more combinators. Look in the Glossary to find them. Some notable ones include:

bi
bi*
bi@
tri
tri*
tri@
dip
sip