(BLOCK x) => x
(BLOCK (v := x) . rest)
=> ((LAMBDA (v) (BLOCK . rest)) x)
(BLOCK (vars := . values) . rest)
=> ((LAMBDA vars (BLOCK . rest)) . values)
(BLOCK (x :=: y) . rest)
=> ((LAMBDA (x y) (BLOCK . rest)) y x)
(BLOCK x . rest) => ((LAMBDA (A B) (B))
x
(LAMBDA () (BLOCK . rest)))
Let us now consider a rule for the more complicated COND construct:
(COND) => 'NIL (COND (x) _ rest) => (OR x (COND _ rest)) (COND (x . r) . rest) => (IF x (BLOCK . r) (COND . rest))
This defines the "extended" COND of modern LISP systems, which produces NIL if no clauses succeed, which returns the value of the predicate in the case of a singleton clause, and which allows more than one consequent in a clause. An important point here is that one can write these rules in terms of other macro constructs such as OR and BLOCK; moreover, any extensions to BLOCK, such as the limited assignment feature described above, are automatically inherited by COND. Thus with the above definition one could write
(COND ((NUMBERP X) (Y := (SQRT X)) (+ Y (SORT Y)))
(T (HACK X)))
where the scope of the variable Y is the remainder of the first COND clause.
SCHEME also provides macros for such constructs as DO and PROG, all of which expand into similar kinds of code using LAMBDA, IF, and LABELS (see below). In particular, PROG permits the use of GO and RETURN in the usual manner. In this manner all the traditional imperative constructs are expressed in an applicative manner. {Note ASET' Is Imperative} [1]
None of this is particularly new; theoreticians have modelled imperative
- ↑ {Note
ASET'Is Imperative}It is true that
ASET'is an actual imperative which produces a side effect, and is not expressed applicatively.ASET'is used only for two purposes in practice: to initialize global variables (often relating to MacLISP primitives), and to implement objects with state (cells, in the PLASMA sense [Smith and Hewitt] [Hewitt and Smith]). If we were to redesign SCHEME from scratch, I imagine that we would introduce cells as our primitive side-effect rather thanASET'. The decision to useASET'was motivated primarily by the desire to interface easily to the MacLISP environment (and, as a corollary, to be able to implement SCHEME in three days instead of three years!).We note that in approximately one hundred pages of SCHEME code written by three people, the non-quoted ASET has never been used, and
ASET'has been used only a dozen times or so, always for one of the two purposes mentioned above. In most situations where one would like to write an assignment of some kind, macros which expand into applicative constructions suffice.