Quotations and Closures

In Smojo, a quotation defines a word with no name. When a quotation is run, it produces an XT with no name ( that is no named entry in the Dictionary. ) Such nameless XTs produced from Quotations are called closures. However, apart from the "namelessness", there is absolutely no difference between closures and ordinary XTs. As you will see later, Quotations are extremely useful in Smojo programming.

Word Action
:> and  ;
These words define a quotation in interpretation mode only, resulting in a closure (i.e., an XT) on the stack.
[: and ;]
These words also define a quotation but are only applicable in compilation mode. When the enclosing word is run, a closure is created on the stack.
EXECUTE
This word will run any XT on the stack, whether closures created from quotations or XTs of words obtained by ticking.

Some Examples

Quotations in Interpretation Mode.
	:> "I have no name!" . ; 
	execute
	I have no name! ok
	

In this example, the closure is pushed onto the stack. 
EXECUTE
pops it from the stack and runs it.

Quotations in Compilation Mode.
	: hello [: "I have a name!" . ;] ;
	hello .S
	execute

	<1> com.terraweather.mini.XT@77ff2061 
	I have a name! ok
	

Compared to the previous Example, this closure is only created and pushed onto the stack when the enclosing word 
HELLO
is run.

Lexical Closures

Take a hard look at this word:

	: div? ( n -- xt ) 
		{ n } [: n mod 0 = ;] ;
	

DIV?
obviously encloses a Quotation. This quotation defines a word that checks if a number on the stack is divisible by N, which is determined at the time the closure is created. For example:

	32 div? decompile 

	[0]	Literal<32>
	[1]	MOD
	[2]	Literal<0>
	[3]	=
	ok
	

The decompilation shows that the code section of the closure is
32 MOD 0 =
. Notice that the number (N=32) has been compiled into the closure as a literal. These types of closure are historically known as "lexical closures". All closures in Smojo are "lexical". ( The alternative is a situation where the determination of the value of N is delayed to the runtime environment of the closure. Such closures are "dynamic". It is easily possible to create dynamic closures in Smojo, but historically this is known to lead to hard-to-debug code. )

Key idea: Smojo will always automatically replace locals defined in the enclosing environment as Literals when it creates closures. To see this try

1749 div? decompile

Functional Composition

Quotations are often used to create new functionality via composition at runtime (vs doing this statically at compilation time). A simple example:

	: ** ( xt xt -- xt ) 
		{ f g } [: f execute g execute ;] ;
	0 ' sin ' cos ** execute .
	1.0 ok
	

**
takes two XTs and returns a new XT, resulting in a composition function. Mathematically, the example is just: g(f(x)) = cos(sin(x))

A better and more efficient way to write 
**
is using the word
~
which converts an XT into an executable local:

 : ** ( xt xt -- xt )      
                ~ { g } ~ { f } [: f g ;] ;
        0 ' sin ' cos ** execute .
        1.0 ok
        

Quiz

Question 1

 In the last example, use decompilation to compare the closures from the first and second version of 
**
. Which is more efficient? Why?



Question 2

Can ordinary locals be used within a quotation? Prove your answer with a program.



Question 3*

 Write a word 
DX ( xt -- xt )
, which given a mathematical function, f(x) returns another function which approximates its derivative, df/dx. Hint: you can use the simple Euler method.

Question 4

 Write a word 
DX2 ( xt -- xt )
which approximates the second derivative, d2f/dx2. Can you re-use your answer to Question 3?



Question 5**

 We could have designed the word 
DX
to take both a number x0 and a function to give the value of the derivative at x0. That is,
DX ( n xt -- n )
. Compare in detail this design choice to the one taken in Questions 3 and 4.



Next: Sequences