Quoting

As shown in the previous chapter, the syntax of tourniquet is quite simple: a function is defined by its name, followed by :=, followed by a sequence of functions (the functions being separated by whitespace), and finally ended with a semicolon (;).

But there is an additional bit of the syntax that we must address: quoting. The only way in which round brackets/parentheses ((, )) are used in tourniquet is for quotation. Wrapping a sequence of zero or more functions inside of parentheses results in the sequence itself being pushed onto the top of the stack. This effectively creates an anonymous function, and then pushes it onto the stack.

Quoting is important for some purposes. For example, there is a built-in function called if that serves the same purpose as “if” statements in other languages — that is, it allows for conditional execution. Say that we wanted to define a function similar to add_one (defined in the previous chapter), but have it only add one when the other summand is odd. That way, the resulting integer is always even. We could do that like so:

make_even := dup 2 % 0 = () (1 +) if;

And we could visualise the application of this function like so, assuming that we start with 3 on top of the stack:

┄┄┄┲━━━┓
 … ┃ 3 ┃
┄┄┄┺━━━┛
↓ dup
┄┄┄┲━━━┳━━━┓
 … ┃ 3 ┃ 3 ┃
┄┄┄┺━━━┻━━━┛
↓ 2
┄┄┄┲━━━┳━━━┳━━━┓
 … ┃ 3 ┃ 3 ┃ 2 ┃
┄┄┄┺━━━┻━━━┻━━━┛
↓ %
┄┄┄┲━━━┳━━━┓
 … ┃ 3 ┃ 1 ┃
┄┄┄┺━━━┻━━━┛
↓ 0
┄┄┄┲━━━┳━━━┳━━━┓
 … ┃ 3 ┃ 1 ┃ 0 ┃
┄┄┄┺━━━┻━━━┻━━━┛
↓ =
┄┄┄┲━━━┳━━━━━━━┓
 … ┃ 3 ┃ false ┃
┄┄┄┺━━━┻━━━━━━━┛
↓ ()
┄┄┄┲━━━┳━━━━━━━┳━━━━┓
 … ┃ 3 ┃ false ┃ () ┃
┄┄┄┺━━━┻━━━━━━━┻━━━━┛
↓ (1 +)
┄┄┄┲━━━┳━━━━━━━┳━━━━┳━━━━━━━┓
 … ┃ 3 ┃ false ┃ () ┃ (1 +) ┃
┄┄┄┺━━━┻━━━━━━━┻━━━━┻━━━━━━━┛
↓ if
┄┄┄┲━━━┓
 … ┃ 4 ┃
┄┄┄┺━━━┛

dup is a built-in function that duplicates the value that’s on top of the stack. % is a built-in function that performs the modulo operation, using the same nomenclature as other languages like C, Python, Rust, etc. And, as mentioned before, sequences of functions can possibly be empty (i.e. length of zero), so () represents a quotation of the identity function (the function that does nothing to the stack).

Finally, the built-in function if consumes the top three values on the stack. The bottom such value is a boolean value that determines whether the first function (if it’s true), or the second function (if it’s false), is applied. The middle such value is the first function, and the top such value is the second function.

app

Closely related to quotation is the built-in function app. app is short for apply, which means that it simply applies the function that is on top of the stack. The most clear way to see how app works is to observe that the following two functions are equivalent (using the same example from the previous chapter):

add_one := 1 +;

add_one' := (1 +) app;