retroforth/doc/QuotesAndCombinators.md
crc e549b4ced6 no longer use ```` for code blocks; this fence sequence will be used for embedded tests in a later update
FossilOrigin-Name: dfed0de00b8d63672a882b79c4951cce0076007ef208c063b2f4e54fe9bd08f8
2018-04-25 16:57:28 +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! puts ] if

Or if it's FALSE:

  #1 #2 eq?
  [ 'Not_true! puts ] -if

There's also a choose combinator:

  #1 #2 eq?
  [ 'True! puts     ]
  [ 'Not_true! puts ] choose

RETRO also uses combinators for loops:

A counted loop takes a count and a quote:

  #0 #100 [ dup putn 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 [ putc ] 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