SketchyLISP Reference |
Copyright (C) 2006 Nils M Holm |
[<<Summary] | [Contents] [Index] | [Reduction Rules>>] |
Each SketchyLISP expression is a program and each program is an
expression. Programs are executed
by reducing them to their
normal forms. An expression is in its normal form, if it cannot
be reduced any further. The interpreter prints the result of each
expression that has been read at the top level. The context of an
expression is the top level, if the expression has been entered at
the user's terminal (or redirected from a file).
The interpreter makes no difference between upper and lower case characters, but it folds all input to lower case.
There are multiple types of SketchyLISP expressions:
The notation ()
represents the
empty list.
Symbols, booleans, procedures, numbers, chars, and strings are called atoms or atomic expressions, because they cannot be decomposed.
A symbol is represented by a name composed of these ASCII characters:
abcdefghijklmnopqrstuvwxyz 0123456789 * + - / < = > _ ? !
A pair is used to glue
two expressions
together. Is is represented by the form
(x . y)
where x and y may be of any type. The x part of a pair is also called its car part and the y part is called its cdr part part. A pair is also said to be of the type cons.
Note that the Scheme standard requires a blank character before and after the dot separating the car and cdr part of a pair. SketchyLISP does not require this blank, so above pair could be written as:
(x.y)
A list is a pair whose cdr field is
either another pair or ()
. The only exception is
the empty list which does not have a car nor a cdr part. Each list
of the form
(a1 . (a2 . ... (aN . ()) ... ))
may also be written as
(a1 a2 ... aN)
The second form is equivalent to the first one, but easier to read.
Lists whose last members are not equal to ()
are called improper lists.
Such lists have an atom in their last position. They are represented
using pair notation:
(a . b)
or
(a b . c)
The boolean literal
#t
represents logical truth and
#f
represents logical falsity. Note that
#t
merely is the canonical form of the
true
value. Any object that is not identical to
#f
is considered true
.
Integer
numbers (or just integers
)
are represented by lists of digits with an optional leading plus or minus
sign, eg:
314 -159 +265
Integers are the only numbers in SketchyLISP, so the terms integer
and number
are used as synonyms in this document.
Character literals (or just chars
)
are introduced by the prefix #\
. The character to be
represented follows without any blanks in between, for instance:
#\A #\b #\" #\\ #\# #\(
The blank character may be written as #\
, but for
improved readability, the notation #\space
should be
preferred.
String literals (or just strings
)
are sequences of printable characters (including blanks) which are delimited
by double quotes ("
):
"abc" "Foo" "Hello, World!" "\"Hi,\" she said."
As shown above, quote characters may be included in strings by
escaping
them. A character is escaped
by prefixing it with a backslash (\
). To include the
backslash itself in a string, it must be escaped with another backslash:
"A \\ B"
Procedures are represented by lambda functions
of the form
(lambda (args) term)
They will be explained in detail in the following chapters.
Any expression that is prefixed with an apostrophe already is in its normal form. Hence
(+ 5 7) => 12
but
'(+ 5 7) => (+ 5 7)
At any point, a comment may be
placed in an expression by inserting a semicolon (;
).
Each comment extends up to the end of the line it has been started in.
All characters are allowed in comments. To the interpreter, the entire
comment looks like a single space character.
The readable notation of a SketchyLISP (or Scheme) object is called its
external representation.
For example, 123
is the external representation of an
integer with the value 123, "Hello, World!"
is the
external representation of a string with the content Hello, World!.
The external representation of an object is the form that is used
to store that object externally (i.e. outside of the interpreter).
The write
procedure writes the external representation
of a given expression to the output stream. The read
procedures reads the external representation of an expression and
stores it internally.
Most objects that can be written using write
have an
unambiguous external representation. When writing such an object and
then re-reading it, the original object and the object read are
guaranteed to be equal (but not identical). Objects that do not have
unambiguous external representations cannot be re-read and hence cause
an error when a program attempts to read them.
Objects without an unambiguous external representation include procedures, continuations, the EOF object, and the void object. All these objects are represented using the following notation
#<some informative text>
Here is a summary of all SketchyLISP objects including examples of their external representations:
foo symbol "some text" string 123 integer #\y char (foo . bar) pair (foo bar baz) list #t boolean #<closure (x)> closure #<primitive car> primitive procedure #<special lambda> special form #<continuation> continuation #<eof> end-of-file object #<void> void object
[<<Summary] | [Contents] [Index] | [Reduction Rules>>] |