-
Notifications
You must be signed in to change notification settings - Fork 31
/
reflection.doc
99 lines (86 loc) · 5.05 KB
/
reflection.doc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
(((((((((((((((((((((((((((((((( L i S P ))))))))))))))))))))))))))))))))
This file is derived from the files that accompany the book:
LISP Implantation Semantique Programmation (InterEditions, France)
or Lisp In Small Pieces (Cambridge University Press).
By Christian Queinnec <[email protected]>
The original sources can be downloaded from the author's website at
http://pagesperso-systeme.lip6.fr/Christian.Queinnec/WWW/LiSP.html
This file may have been altered from the original in order to work with
modern schemes. The latest copy of these altered sources can be found at
https://github.com/appleby/Lisp-In-Small-Pieces
If you want to report a bug in this program, open a GitHub Issue at the
repo mentioned above.
Check the README file before using this file.
(((((((((((((((((((((((((((((((( L i S P ))))))))))))))))))))))))))))))))
This file gives some indications on the reflective capabilities as
well as the first-class environments provided by the chapter 8. It is
not a complete specification but only a short sketch of what they
are. You will have to read the book to know more about these features
and chiefly how to implement them in a byte-code compiler.
The export special form returns a first-class environment capturing
bindings. Two forms exist:
(export variable-names ... )
captures all the mentioned variables whether global or local.
(export)
captures all variables whether global or local. This is something
that might be also called (the-environment).
First-class environments are useful with a binary eval function named
eval/b in the book.
(eval/b <expression> <environment>)
returns the value of the expression considered as a program to be
evaluated in the specified environment. Free variables of the
expression take their value from the environment. An error is
signalled if a variable is missing from that environment ie the
environment cannot be automatically enriched with new bindings.
A first-class environment may be enriched to contain a new
variable. This is the role of the enrich function that returns a new
environment containing locations associated to the given names.
(enrich <environment> (quote variable-name) ... )
The first argument is not modified but a new first-class environment is
built instead. The fresh bindings may shadow old bindings with the same
name.
A proposal to make closures less opaque is provided with the following
special form:
(reflective-lambda (variables) (exportations) . body)
The variables mentioned in the exportations are the only bindings that
may be used out of the closure if retrieving them, packed in a first-class
environment, with the following function:
(procedure->environment <closure>)
Better than eval/b, first-class environments may be used more statically
within import forms. The import special form is the following:
(import (variables) <environment> . body)
First, the environment is evaluated then the body is evaluated in an
extended environment where the free variables of body that are mentioned
in (variables) are assimilated to the locations with the same name in the
environment. This means that body only pays for the variables that appear
in (variables), a static list of variable names. It is suggested in the book
that if you do not mention variables then all free variables of body are
looked up in the provided environment. This is somewhat similar to the
quasi-static scope of Lee and Friedman POPL92.
I use it from place to place to control exceptions. The monitor special
form takes care of them:
(monitor handler . body)
First handler is evaluated and must yield a binary function then the
body is evaluated and its final value is returned. If an exception occurs
(and exceptions may be raised explicitly with the diagnose function:
(diagnose boolean value)
signals value as an exception whose continuability is specified by boolean)
then the dynamically most recently enclosing handler is appplied on a boolean
and an exceptional value. This application is controlled by the next most
recently dynamically enclosing handler. The botttom handler is left
unspecified. If the handler returns a value, this value becomes the value
of the diagnose call only if the boolean was true (meaning that it was a
continuable exception) otherwise a "non continuable" exception is raised.
Another part of chapter 8 presents a reflective interpreter whose main
features are:
the continuation can be accessed with the call/cc function,
the entire environment may be accessed with the the-environment special form,
the global environment is the value of the global-environment variable,
the enrich, eval/b, monitor features are present,
reflective forms are created with flambda.
(flambda (r . variables) body)
returns a reflective object which when applied receives the current lexical
environment in its first variable and the unevaluated arguments in its
remaining variables (this is nearly equivalent to the old fexprs).
Of course, the interpreter can interpret itself.
#end of reflection.doc