Scheme
註釋

↑  
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin.  (PDF) 2nd. MIT Press. 1985 [1962]  [2021-10-25]. ISBN 0-262-13011-4. （原始内容 (PDF)存档于2021-03-02）. The variables in a lambda expression are dummy or bound variables because systematically changing them does not alter the meaning of the expression. Thus λ[[u;v];v2+u] means the same thing as λ[[x;y];y2+x].
We shall sometimes use expressions in which a variable is not bound by a lambda. For example, in the function of two variables λ[[x;y];xn+yn] the variable n is not bound. This is called a free variable. It may be regarded as a parameter. Unless n has been given a value before trying to compute with this function, the value of the function must be undefined. ……
When the compiler is called upon to compile a function, it looks for an EXPR or FEXPR on the property list of the function name. The compiler then translates this S-expression into an S-expression that represents a subroutine in the LISP Assembly Language (LAP). LAP then proceeds to assemble this program into binary program space. Thus an EXPR, or an FEXPR, has been changed to a SUBR or an FSUBR, respectively. ……
Free variables in compiled functions must be declared before the function is compiled. ……
A variable is bound in a particular function when it occurs in a list of bound variables following the word LAMBDA or PROG. Any variable that is not bound is free. ……
When a variable is used free, it must have been bound by a higher level function. If a program is being run interpretively, and a free variable is used without having bee bound on a higher level, error diagnostic *A 8* will occur.
If the program is being run complied, the diagnostic may not occur, and the variable may have value NIL. 
There are three types of variables in compiled functions: ordinary variables, SPECIAL variables, and COMMON variables. SPECIAL and COMMON variables must be declared before compiling. Any variable that is not declared will be considered an ordinary variable.
When functions are translated into subroutines, the concept of a variable is translated into a location where an argument is stored. If the variable is an ordinary one, then a storage location for it is set up on the push-down list. Other functions cannot find this private cell, making it impossible to use it as a free variable.
SPECIAL variables have the indicator SPECIAL on their property lists Following the indicator there is a pointer to a fixed cell. When this variable is bound, the old value is saved on the push-down list, and the current value is stored in the SPECLAL cell. When it is no longer bound, the old value must be restored. When a function uses this variable free, then the quantity in the SPECIAL cell is picked up.
SPECIAL variables are declared by using the pseudo-function special[a], where a is a list of variable names. ……
SPECIAL variables are inexpensive and will allow free communication among compiled functions. They do not increase run time significantly. SPECIAL variables cannot be communicated between the interpreter and compiled functions.
COMMON variables have the flag COMMON on their property lists; however, this is only used to inform the compiler that they are COMMON, and is not needed at run time. COMMON variables are bound on an a-list by the compiled functions. When they are to be evaluated, eval is given this a-list. This happens at run time.
The use of COMMON variables will slow down any compiled function using them. However, they do provide complete communication between interpreted and compiled functions.
COMMON variables are declared by common[a], where a is a list of variable names. ……
LISP is designed in such a way that all functions for which the possibility of recursion can exist are in fact recursive. This requires that all temporary stored results related to the computation that is in progress be set aside when a piece of coding is to be used recursively, and that they be later restored. This is done automatically and need not be programmed explicitly.
All saving of temporary results in LISP is performed on a linear block of storage called the push-down list. Each set of stored data that is moved onto the push-down list is in a block labeled with its size and the name of the subroutine from which it came. Since it is in the nature of recursion that the first block to be saved is always the last block to be restored, it is possible to keep the push-down list compact. 

Joel Moses（英语：）.  (pdf). June 1970  [2009-10-27]. AI Memo 199. （原始内容存档于2010-05-23）. There are several ways in which to maintain the values of free variables (and, thus the computational environment) in order to handle cases like the one above. All of the techniques used involve some increase in time. One approach makes it easy to access the value of a free variable is local. This approach is favored in recent implementations of LISP. We shall call it the "shallow access" approach.
Another approach is to make it relatively easy to enter and leave a block in which a free variable is bound, but relatively expensive to access a free variable. This approach is used in the classical "alist" implementation of LISP. Several Algol systems have opted for a similar approach. We shall call this the "deep access" approach. Both of these approaches allow one to modify the value of the variable as well as access it. The access time is approximately the same as modification time in both approaches.
Let us consider the "shallow access" approach first. By "shallow access" we mean that the value of a free variable can be obtained in a single fetch from memory. Since the current value may be stored in a difficult-to-determine location up in the stack, a special cell for its current value is used. In many recent LISP implementations this special values cell is stored as a property of the atom structure, and is unique to the free variable. In order to maintain the proper value in the special cell, extra work must be done every time a function or a block is entered in which the variable is an argument or is local. On entering such a function or block one usually saves the old value which is in the special cell on the stack alone with sufficient information to allow one to know from where the stack value came. On leaving such a function or block one must remember to store the value saved in the stack in the special cell.
The "deep access" approach forces one to search upward in the stack for the most recent value of the free variable. Such a search may be quite deep and slow if the free variable was bond vary far up in the stack. However, this approach has the advantage of avoiding  the need for an extra special value cell. In addition, we shall see later that this approach sometimes allows one to use free variables with greater ease and flexibility than the "shallow access" approach. ……
Certain LISP systems use "deep access" in interpreted functions and "shallow access" in compiled functions. if free variables in compiled functions are declared to be COMMON, their values will be stored on the "alist". In this manner one can solve the environment problem. The cost is a very slow interpreter and "deep access" to free variables.
↑  van Tonder, André. . SIAM Journal on Computing. 1 January 2004, 33 (5): 1109–1135. S2CID 613571. arXiv:quant-ph/0307150 . doi:10.1137/S0097539703432165.
↑  
Niehren, J.; Schwinghammer, J.; Smolka, G.  (PDF). Theoretical Computer Science. November 2006, 364 (3): 338–356  [2021-11-07]. doi:10.1016/j.tcs.2006.08.016. （原始内容 (PDF)存档于2022-04-08）.
1 2  
Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. 
DEFINE － This is analogous to the MacLISP DEFUN primitive (but note that the LAMBDA must appear explicitly!). It is used for defining a function in the "global environment" permanently, as opposed to LABELS (see below), which is used for temporary definitions in a local environment. DEFINE takes a name and a lambda expression; it closes the lambda expression in the global environment and stores the closure in the LISP value cell of the name (which is a LISP atom). ……
LABELS － We have decided not to use the traditional LABEL primitive in this interpreter because it is difficult to define several mutually recursive functions using only LABEL. The solution, which Hewitt [Smith and Hewitt] also uses, is to adopt an ALGOL-esque block syntax:
  (LABELS <function definition list> <expression>)
This has the effect of evaluating the expression in an environment where all the functions are defined as specified by the definitions list. Furthermore, the functions are themselves closed in that environment, and not in the outer environment; this allows the functions to call themselves and each other recursively. 
Gerald J. Sussman, Guy L. Steele Jr. . 1978  [2021-11-07]. （原始内容存档于2022-04-06）. Atoms which are not atomic symbols (identifiers) evaluate to themselves. Typical examples of such atoms are numbers, arrays, and strings (character arrays). Symbols are treated as identifiers or variables. They may be lexically bound by lambda-expressions. There is a global environment containing values initially have as their values primitive operations such as, for example, CAR, CONS, and PLUS. SCHEME differs from most LISP systems in that the atom CAR is not itself an operation (in the sense of being an invocable object, e.g. a valid first argument to APPLY), but only has one as a value when considered as an identifier.
↑  .   [2024-01-13]. （原始内容存档于2024-02-26）.
↑  .   [2024-01-06]. （原始内容存档于2024-01-06）.
↑  
Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1976 （英文）. Lambda calculus (and related languages, such as "pure LISP") is often used for modelling the applicative constructs of programming languages. However, they are generally thought of as inappropriate for modelling imperative constructs. …… we show how imperative constructs may be modelled by applicative SCHEME constructs. ……
Up to now we have thought of SCHEME’s LAMBDA expressions as functions, and of a combination such as (G (F X Y)) as meaning “apply the function F to the values of X and Y, and return a value so that the function G can be applied and return a value ...” But notice that we have seldom used LAMBDA expressions as functions. Rather, we have used them as control structures and environment modifiers. For example, consider the expression:
  (BLOCK (PRINT 3) (PRINT 4))
This is defined to be an abbreviation for:
  ((LAMBDA (DUMMY) (PRINT 4)) (PRINT 3))
We do not care about the value of this BLOCK expression; it follows that we do not care about the value of the (LAMBDA (DUMMY) ...). We are not using LAMBDA as a function at all.
It is possible to write useful programs in terms of LAMBDA expressions in which we never care about the value of any lambda expression. We have already demonstrated how one could represent any “FORTRAN” program in these terms: all one needs is PROG (with GO and SETQ), and PRINT to get the answers out. The ultimate generalization of this imperative programming style is continuation-passing. ……
…… we will consider the problem of dynamically scoped, or "fluid", variables. These do not exist in ALGOL, but are typical of many LISP implementations, ECL, and APL. We will see that fluid variables may be modelled in more than one way, and that one of these is closely related to continuation-passing.
↑  
Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. It is always possible, ……to perform any calculation in this way: rather than reducing to its value, it reduces to an application of a continuation to its value (cf. [Fischer]). That is, in this continuation-passing programming style, a function always "returns" its result by "sending" it to another function.
↑  Gerald J. Sussman, Guy L. Steele Jr. . 1978. Non-atomic forms are divided by the evaluator into two classes: combinations and "magic (special) forms". …… Magic forms are recognized by then presence of a "magic (reserved) word" in the car position of the form. All non-atomic forms which are not magic forms are considered to be combinations. The system has a small initial set of magic words; there is also a mechanism for creating new ones {Note FUNCALL is a Pain}.
A combination is considered to be a list of subforms. These subforms are all evaluated. The first value mub be a procedure; it is applied to the other values to get the value of the combination. There are four important points here:
(1) the procedure Position is always evaluated just like any other position. (This is why the primitive operators are the values of global identifiers.)
(2) the procedure is never "re-evaluated"; if the first subform fails to evaluate to a applicable procedure, it is an error. Thus, unlike most LISP systems, SCHEME always evaluates the first subform of a combination exactly once.
(3) the arguments are all completely evaluated before the procedure is applied; that is, SCHEME, like most LISP systems, is an applicative-order language. Many SCHEME programs exploit this fact.
(4) the argument forms (and procedure form) may in principle be evaluated in any order. This is unlike the usual LISP left-to-right order. (All SCHEME interpreters implemented so far have in fact performed left-to-right evaluation, but we do not wish programs to depend on this fact. Indeed, there are some reasons why a clever interpreter might want to evaluate them right-to-left, e.g. to get things on a stack in the correct order.)
↑  
Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. 
BLOCK － This is like the MacLISP PROGN, but arranges to evaluate its last argument without an extra net control frame (explained later), so that the last argument may involved in an iteration. Note that in SCHEME, unlike MacLISP, the body of a LAMBDA expression is not an implicit PROGN. 

Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1976 （英文）. At this point we are almost in a position to model the most general form of compound statement. In LISP, this is called the "PROG feature". In addition to statement sequencing and GO TO statements, one can return a value from a PROG by using the RETURN statement.
Let us first consider the simplest compound statement, which in SCHEME we call BLOCK. Recall that
    (BLOCK S1 S2) is defined to be ((LAMBDA (DUMMY) S2) S1)
Notice that this not only performs S1 before S2, but also returns the value of S2. Furthermore, we defined (BLOCK S1 S2 ... Sn) so that it returns the value of Sn. Thus BLOCK may be used as a compound expression, and models a LISP PROGN, which is a PROG with no GO TO statements and an implicit RETURN of the last "statement" (really an expression). 

Gerald J. Sussman, Guy L. Steele Jr. . 1978. 
(BLOCK x1 x2 ... xn)
    (BLOCK x) → x
    (BLOCK x . r) → ((LAMBDA (A B) (B)) x (LAMBDA () (BLOCK . r)))
BLOCK sequentially evaluates the subforms xi from left to right. For example:
    (BLOCK (ASET' X 43) (PRINT X) (+ X 1))
returns 44 after setting x to 43 and then printing it {Note BLOCK Exploits Applicative Order}.
(LET ((v1 x1) (v2 x2) ... (vn xn)) . body)
    → ((LAMBDA (v1 v2 ... vn) (BLOCK . body)) x1 x2 ... xn)
LET provides a convenient syntax for binding several variables to corresponding quantities. It allows the forms for the quantities to appear textually adjacent to their corresponding variables. Notice that the variables are all bound simultaneously, not sequentially, and that the initialization form xi may be evaluated in any order. For convenience, LET also supplies a BLOCK around the forms constituting its body.
↑  Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. DO － This is like the MacLISP "new-style" DO; old-style DO is not supported.
↑  Gerald J. Sussman, Guy L. Steele Jr. . 1978  [2021-11-07]. （原始内容存档于2022-04-06）. Another difference from LISP is that SCHEME is implemented in such a way that tail-recursions execute without net growth of the interpreter stack. The effect of this is that a procedure call behaves like a GOTO and thus procedure calls can be used to implement iterations, as in PLASMA.
↑  
Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. CATCH － This is the "escape operator" which gives the user a handle on the control structure of the interpreter. The expression:
  (CATCH <identifier> <expression>)
evaluates <expression> in an environment where <identifier> is bound to a continuation which is "just about to return from the CATCH"; that is, if the continuation is called as a function of one argument, then control proceeds as if the CATCH expression had returned with the supplied (evaluated) argument as its value. ……
As another example, we can define a THROW function, which may then be used with CATCH much as they are in LISP:
  (DEFINE THROW (LAMBDA (TAG RESULT) (TAG RESULT)))
↑  David Madore, "call/cc mind-boggler" Portuguese Web Archive的存檔，存档日期2011-01-22
↑  Yin Wang, "Understanding the Yin-Yang Puzzle"
↑  Richard P. Gabriel（英语：）; Kent M. Pitman（英语：）. . Lisp and Symbolic Computation. June 1988, 1 (1): 81–101  [2021-11-08]. S2CID 26716515. doi:10.1007/bf01806178. （原始内容存档于2006-11-13）.
↑  Taylor Campbell. . The SRFI Editors, schemers.org. 2005-07-21  [2012-08-09]. （原始内容存档于2022-04-11）.
↑  Gerald J. Sussman, Guy L. Steele Jr. . 1978  [2021-11-07]. （原始内容存档于2022-04-06）. Syntactic Extensions － SCHEME has a syntactic extension mechanism which provides a way to define an identifier to be a magic word, and to associate a function with that word. The function accepts the magic form as an argument, and produces a new form; this new form is then evaluated in place of the original (magic) form. This is precisely the same as the MacLISP macro facility.
↑  Kohlbecker, E.; Friedman, D. P.; Felleisen, M.; Duba, B.  (PDF). . 1986  [2021-11-10]. （原始内容 (PDF)存档于2017-08-29）. In most current Lisp systems the expander's task is confined to the process of finding syntactic extensions and replacing them by their expansions. This implies, in particular, the each macro function is responsible for the integrity of the program. For Lisp systems (and other languages with similar macro facilities) this means specifically that variable binding  must not be corrupted. This, however, is not as simple a task as it sounds. ……
The real danger of these erroneous macros is that they are treacherous. They work in all cases but one: when the user － or some other macro writer － inadvertently picks the wrong identifier name.
Various techniques have been proposed to circumvent this capturing problem, but they rely on the individual macro writer. if even one of many macro writers is negligent, the macro system becomes unsafe. We claim that the task of safely renaming macro-generated identifier is mechanical. It is essentially an α-conversion, which is knowledgeable about the origin of the identifiers. For these reasons we propose a change to the navïe macro expansion algorithm which automatically maintains hygienic conditions during expansion time. 
Kohlbecker, E; Wand, M.  (PDF). . 1987  [2021-11-10]. （原始内容 (PDF)存档于2022-04-12）.
↑  William Clinger and Jonathan Rees, editors. . ACM Lisp Pointers. 1991, 4 (3): 1–55  [2012-08-09]. （原始内容存档于2022-01-22）.
↑  Flatt, Matthew. . . 2016: 705–717. ISBN 978-1-4503-3549-2. S2CID 15401805. doi:10.1145/2837614.2837620.
1 2  Philip L. Bewig. . The SRFI Editors, schemers.org. 2008-01-24  [2012-08-09]. （原始内容存档于2021-03-07）.
↑  Gerald J. Sussman, Guy L. Steele Jr..  . 维基文库. 1975 （英文）. EVALUATE － This is similar to the LISP function EVAL. It evaluates its argument, and then evaluates the resulting s-expression as SCHEME code.
1 2  . ACM SIGPLAN, Lisp Pointers, Volume V, Issue 4. 1992  [2021-11-12]. （原始内容存档于2022-04-04）.
↑  
Gerald J. Sussman, Guy L. Steele Jr. . 1978  [2021-11-07]. （原始内容存档于2022-04-06）. 
  (ENCLOSE fnrep envrep)
ENCLOSE takes two s-expressions, one representing the code for a procedure, and the other representing the (lexical) environment in which is to run. ENCLOSE returns a (closed) procedure which can be invoked.
The representation of the code is the standard s-expression description (a lambda-expression). the representation of the environment is an association list (a-list) of the traditional kind:
  ((var1 . value1) (var2 . value2) ...)
NIL represents the global lexical environment. ……
The EVALUATE primitive described in [SCHEME] has been removed from the language. We discovered (the hard way) that the straightforward implementation of EVALUATE (evaluate the given expression in the current environment) destroys referential transparency（英语：）. We then altered it to evaluate the expression in the top-level environment, but were still disturbed by the extent to which one is tied to a particular representation of a procedure to be executed.
↑  William D Clinger. . The SRFI Editors, schemers.org. 1999-07-01  [2012-08-09]. （原始内容存档于2021-10-21）.
↑  Scott G. Miller. . The SRFI Editors, schemers.org. 2002-06-25  [2012-08-09]. （原始内容存档于2022-05-08）.
↑  . The SRFI Editors, schemers.org. 2009-08-30  [2012-08-09]. （原始内容存档于2021-06-20）.
↑  .   [2022-11-14]. （原始内容存档于2022-11-04）.
↑  Brian Harvey, Matthew Wright. . 1999  [2021-11-07]. （原始内容存档于2022-05-04）.
↑  Eric Grimson. . MIT Open Courseware. Spring 2005  [2009-10-20]. （原始内容存档于2009-10-01）.
↑  Alex Vandiver, Nelson Elhage;  et al. . MIT CSAIL. January 2009  [2009-10-20]. （原始内容存档于2009-08-28）.  引文格式1维护：显式使用等标签 (link)
↑  Brian Harvey. . UC Berkeley Webcasts. Spring 2011  [2011-12-18]. （原始内容存档于2016-03-16）.
↑  John DeNero. . UC Berkeley. Fall 2011  [2011-12-18]. （原始内容存档于2011-12-29）.
↑  Dov Grobgeld. . The GIMP Team. 2002  [2009-10-20]. （原始内容存档于2010-01-24）.
↑  . Free Software Foundation.   [2009-10-20]. （原始内容存档于2016-03-04）.
Gerald Jay Sussman