-
Notifications
You must be signed in to change notification settings - Fork 24
A: Core Evaluation Models for Scheme
VermillionAzure edited this page Jan 20, 2018
·
1 revision
How might one implement Scheme?
Scheme is considered a member of the greater Lisp programming language family, but it diverges from it in a few majors ways:
-
Macros - Lisp-expression based macros have been around for quite a long time, but many forms of it have existed over its history:
defmacro
for procedural macros,syntax-case
macros, and declarativesyntax-rule
macros. Currently, Scheme has settled on the declarative, pattern-matching basedsyntax-rule
macros. - "Lisp-1" style namespacing - Unlike Common Lisp, another major branch of the Lisp programming language family, Scheme places every variable in a common namespace -- this means that functions and variables names must share the same pool of name possibilities to choose from.
-
First-class undelimited continuations - Many concepts share the name "continuation," from the procedures that definite continuation-passing style (CPS) intermediate representation (IR) to undelimited continuations (call-cc) to delimited continuations (shift/reset). Scheme (R7RS) supports the
call-with-current-continuation
model for continuations, which is powerful, but relatively costly to implement. -
Functional language design - Scheme's language design is purposely made to support functional programming and make mutation/side-effects explicit by the
side-effect!
naming convention. The result? One can go through the exercises in Structure and Interpretation of Programming Languages with an entirely functional subset of Scheme, and then introduce side-effects as a separate part of it.
- Scheme cannot be evaluated with a purely recursive evaluation model. The symmetry of the "read/eval" recursion that one might find in simpler Lisp designs is explicitly broken by the presence of Scheme's undelimited first-class continuations. The result? One must find a way to explicitly save the state of your evaluation model and restore it as a first-class feature of your chosen representation.
-
Saving and restoring the state of the stack is not explicitly supported as a first-class feature in the C or C++ standards. This is due to the flexibility that both languages wish to give to implementations on different architectures. It is entirely possible to try and do this in native code by actually saving and restoring the memory state of the stack through pointers, but it is undefined behavior, as explored by Bigloo Scheme's work with integrating LLVM.
-
Interop between C and Scheme code even in the presence of
call/cc
has been achieved withsetjmp/longjmp
with Chez Scheme.
- They are not, according to R7RS.
- The standard is mostly silent on this, but the presence of circular lists is explicitly hinted at in the design requirements of certain functions that must ensure they have correct functionality even with the presence in circular lists
- One example: datums that contain circular references and
read
.
- One example: datums that contain circular references and
- Due to how the current
syntax-rules
is defined in the standard, macros capture the scope of their definition. This means that scopes can be assigned to macros to statically decide the bindings of names to scopes. This is exemplified by Racket's macro system, which, at the time of writing, was recently overhauled to take advantage of this with syntax objects.