Embedding Scheme in other applications
This section describes how the SoftwareTamed.Scheme assembly operates within other applications.
Eventually this section will develop into a series of pages describing the various aspects of the interpreter itself.
Types
TameScheme is based on .NETs own type system. Most .NET types make sense to TameScheme, giving it a much richer set of types than most scheme systems. Most types have no special meaning to the interpreter, but some types have some specific meaning.
The interpreter just passes 'unknown' types through; ie, the result of
evaluating a DateTime
object, for example, is just the
DateTime
object.
(An eventual extension will be the notion of 'evaluatable' classes which can provide a different means of evaluation if they're encountered)
Pairs
The Pair
class represents a scheme pair. It consists of a
Car
and a Cdr
field, which can
both be any type of object. As far as Scheme itself is concerned, this is
all there is to a pair.
However, a scheme pair has a few properties that can be better exposed via
.NET interfaces. Consequently, the Pair
implements the
IList
, allowing it to be used in many circumstances
where a .NET list class can be. There are some 'oddities' related to the
slightly differing nature of a Pair to a 'standard' .NET list which may
limit the usefulness of these functions.
Improper lists are not .NET lists. For convienience, no error is generated unless the 'improper' element is accessed, however, so improper lists may be useful in some circumstances. Neither are self-referential lists: these do not produce errors but may result in infinite loops in some cases.
The .NET list interface is designed on the assumption that the 'list' is
contained by the class and is not (as in the case of Pairs) the class
itself. This means that it is not sensible to remove the only element
in a scheme list containing a single value. The .NET 'null' value
represents an empty list, and the scheme specification states that
an empty list is not a Pair. Use myPair = myPair.Cdr
as code
to remove the first element in a list wherever you possibly can.
Normally removing (or inserting) an element will just result in an elements Cdr being changed, but this is not always possible, so some operations will result in an element being overwritten. In particular, inserting or removing at the beginning of a Pair list will result in the first element being overwritten with the new value. The consequences are subtle, but may be significant in some circumstances.
Consequences of removing parts of a Pair
Given the pair (1 2 3)
, stored in the object somePair
,
the result of somePair.Remove(1)
is that somePair.Cdr is changed
to point to (3)
(the tail of the pair). somePair.Cdr.Remove(0)
however, has a new effect. It changes the pair representing (2 3)
(the Cdr of pair) with the pair (3)
. somePair.Cdr
is NOT changed, but instead its value is modified.
Pairs can be constructed from any object implementing the ICollection interface. This produces a well-formed scheme list from the contents of the collection.
Symbols
The Symbol
is used to represent scheme symbols. It effectively
contains a single number: a reference into the SymbolTable
class. There is only one symbol table per process: so each symbol is
uniquely identified by its number within that process.
Numbers
The .NET number classes (int, float, etc) represent the corresponding scheme number types. In addition, there are three scheme number classes representing types of number that are part of the set of scheme types but not available from .NET.
These classes are Rational
, RationalComplex
and
Complex
, which represent respectively an exact rational number,
an exact complex number and an inexact complex number.
Note that presently a decimal is treated as an exact floating point number.
However, TameScheme is not presently capable of promoting it to a
Rational
, which limits its usefulness. (.NET 1.1 does
not appear to provide introspection functions that are required for this)
The number classes all implement the INumber
interface
which provides a common means of manipulating them, in addition to some
class-specific functions.