A revised summary, 18 July 2012
The following notes on quotations and closures incorporate
material from several people, including Anton Ertl, Andrew Haley,
Marcel Hendrix, Ward Mcfarland, Bernd Paysan, and Elizabeth
Rather. If you have been left out and want acknowledgement, please
let me know.
Quotations
==========
Discussion
----------
The essence of quotations is to provide nested colon definitions,
in which the inner definition(s) are nameless. The expression
: foo ... [: some words ;] ... ;
is equivalent to
:noname some words ; Constant #temp#
: foo ... #temp# ... ;
A simple quotation is an anonymous colon definition that is
defined inside a colon definition or quotation. It has no access
to locals of the enclosing definitions.
If quotations are to have the same privileges as words defined
with : and :NONAME they should be able to use local variables and
use RECURSE. Quotations should not be able to access the locals of
the outer word because we have no knowledge of when the quotation
is executed and hence whether outer locals are still alive.
One example use of quotations is to provide a solution to the use
of CATCH in a form close to other languages' TRY ... EXCEPT
blocks.
: foo \ i*x -- j*x
setup
[: fee fi fo fum ;] catch
if ... then
teardown
( throw again )
;
Under the term "Phrases", quotations have been in MacForth since
at least 1987. They are documented in the infamous "missing
chapter" of the MacForth manual.
Specification
-------------
The following notations have been seen in the wild, oldest first.
:| ... |;
:[ ... ]:
[: ... ;]
[: ( -- nested-sys )
Compilation: suspends compiling to the current definition, starts a
new
nested definition, and compilation continues with this nested
definition. Outer locals are not visible in the nested definition.
Locals may be defined in the nested definition. Inside the nested
definition RECURSE applies to the nested definition.
;] ( nested-sys -- )
Compilation: Ends the current nested definition, and resumes
compilation
to the previous current definition. It appends the following run-time
to
the current definition:
run-time: ( -- xt )
xt is the execution token to execute the nested definition.
Closures
========
Discussion
----------
A closure is like a quotation, except that it has (read and write)
access to the locals of the enclosing definitions.
Simple quotations are relatively easy to implement, closures are hard,
because they can extend the life of the enclosed locals beyond the end
if their definition; in general garbage collection is needed to manage
the enclosed locals of closures. Therefore everyone up to now has
only seriously thought about implementing and standardizing simple
quotations, and any discussions about closures are just theoretical
exercises.
I have chosen to distinguish nameless words intended as closures
by using [[: ... ;]] to define them. I have also chosen to
distinguish the required persistence of data by declaring it using
{{ ... }} which is syntactically like { ... } locals but has very
different persistence requirements.
: foo {{ a b -- }} ... [[: ... a b ... ;]] execute ;
Knuth's Man-Or-Boy test creates a quotation that *modifies* the
outer locals and then recursively calls its host, accessing outer
locals that one might have expected to long gone out of
scope. It forces the quotation implementation to store copies of
*all imaginable* outer locals and make them permanently available.
This can get even more interesting when a closure is required to
remember not only locals, but things like BASE, >IN, arbitrary
variables, file handles, buffer addresses, etc..(*)
There is a Forth example by Gerry Jackson which provides an
example of lambda definitions. This example is in ANS Forth and
runs on a range of systems.
www.qlikz.org/forth/lambda.zip
Comments
--------
Maybe we first need a convincing example of the usefulness of
quotations and closures.
Aside from looking obscure and clever and satisfying the "[x]
can do it, why not Forth?" test, what on earth does this buy you?
What does a closure achieve that cannot be achieved by other
scoping and persistence mechanisms such as a class and an object
with heap allocation?
Specification
-------------
TBD
--
Stephen Pelc,
steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel:
+44 (0)23 8063 1441, fax:
+44 (0)23 8033 9691
web:
http://www.mpeforth.com - free VFX Forth downloads