Back to index

Datatypes and Operations

This section describes shortly the datatypes supported by LispMe and has links to the procedures associated with them.

Booleans

LispMe has (like Scheme) two standard boolean objects, #f and #t. However, any object other than #f is considered true in logical expressions. This includes (), which is not eq? to #f.

Comparison operators < <= > >= work with numbers, chars and strings, there are no separate comparison functions for them.

Associated language elements

#f #t < <=
> >= and boolean?
case cond eq? eqv?
equal? if not or

Symbols

Symbols are represented just by their names, so two symbols are eq?, if they spell the same. This is insured by the LispMe reader, which maintains a table of all symbols read so far. The size of this table is adjustable in the Preferences dialog via Atom Size.

Associated language elements

eq? gensym symbol?

Numbers

LispMe doesn't implement the entire tower of numerical types described in R4RS. LispMe supports 15 bit signed integers, 64 bit IEEE-754 double precision reals and complex numbers represented as pairs of real numbers. Floating point is only available with PalmOS2. To use transcendental functions, you must install MathLib.

Integer numbers are represented internally as unboxed data, so they can be compared with eq?. Use eqv? to compare arbitrary numbers.

Invalid operations with floating points do not abort the evaluation, but result in special IEEE-defined values infinity, -infinity and not-a-number (or may return complex results!), which print like this. The only exception is division by zero, which always causes an error to be consistent with integer division.

The exactness property of Scheme is not supported, all numbers are considered inexact?.

Associated language elements

* + - / <
<= = > >= abs
acos acosh angle asin asinh
atan atanh ceiling complex? cos
cosh eqv? even? exact? exp
expt floor imag-part inexact? integer
integer? log log10 magnitude make-polar
make-rectangular max min modulo negative?
number? odd? positive? quotient random
real-part real? remainder round sin
sinh sqrt tan tanh truncate
zero?

Characters

LispMe characters are objects representing Pilot's ASCII character codes. They're distinct from integers, but can be converted to/from integers with the char->integer and integer->char procedures.

LispMe doesn't support R4RS procedures char<? etc. but extends the numeric comparison operators < <= > >= to work with characters, too. The ordering defined by these operators is the ordering of the corresponding ASCII codes.

To compare for equal characters, use eq?.

Associated language elements

< <= > >= char->integer
char? eq? integer->char max min

Strings

Strings are mutable sequences of characters. Strings are disjoint from any other data type in LispMe. They're represented internally as DB records of the characters they contain. The maximum length for a string is 16383 characters.

LispMe doesn't support R4RS procedures string<? etc. but extends the numeric comparison operators < <= > >= to work with strings, too. The ordering defined by these operators is the lexicographic extension of the ordering of the underlying characters.

To compare for equal strings, use string=?, as eqv? is required to distinguish non-shared strings.

In LispMe equal written strings (including the empty string) are never shared.

The printing and scanning procedures object->string and string->object use an internal buffer which is limited to 4096 characters.

Associated language elements

< <= > >= list->string
max min object->string string->list string->object
string-append string-length string-ref string-set! string=?
string? substring

Pairs and Lists

Lists are the "working horse" data structures of LispMe. Lists are built from pairs, which contain two arbitrary objects, traditionally called the car and the cdr. The type predicate pair? is used to recognize pairs. pair? does distinguish real pairs from other data structures which may be internally represented as pairs.

Lists are structures built from pairs where every cdr component is either a pair or the special object '() called the empty list.

Associated language elements

'() append assoc assq assv
c...r car cdr cons equal?
length list list->string list-ref map
member memq memv memv null?
pair? reverse set-car! set-cdr! string->list

Vectors

Vectors are heterogenous sequences similar to lists, but each element can be accessed in constant time by an integer index. The first element in a vector has index 0 and the last has the index length of the vector minus one. The maximum length for a vector in LispMe is 16383. Vectors are not allocated on the heap, but each vector is a single record in the LispMe database, so the total amount of vectors is only limited by the available system memory.

Associated language elements

list->vector make-vector vector vector->list
vector-length vector-ref vector-set! vector?

Closures

A closure is a functional object which is created by the lambda special form and contains the compiled form of the LispMe code it is built from together with the lexical environment to bind free variables. See here for more details.

Closures have no sensible written representation, see here how they are printed.

Additionally, LispMe provides the meta-linguistic function eval, which interprets an expression as LispMe code.

Associated language elements

apply disasm eval for-each
lambda map procedure?

Continuations

A continuation is a first-class object representing the future of a computation. At each stage in a evaluation there's a value being computed and a continuation going to do something with this value. Normally these continuations work behind the scenes and programmers don't think much about them. LispMe allows continuations to be captured into continuation objects, which may be stored and called many times and always returns to the same place.

A continuation object can be created by the call/cc procedure, which expects a procedure of one argument. This procedure will be called with the current continuation as its parameter. This continuation looks like a procedure of one argument, but any time it is called afterwards, the argument will be the return value of the original call/cc application.

Continuations are a powerful control mechanism and can be used to implement non-local returns, exception handling, backtracking, or coroutines.

Continuations have no sensible written representation, see here how they are printed.

Associated language elements

call/cc continuation?

Promises

Promises are used to delay the evaluation of an expression and are therefore similar to closures with no arguments. Additionally, once a promise has been forced, the result value overwrites the body of the promise and subsequent forcing always yields the same value without recomputing it.

Promises have no sensible written representation, see here how they are printed.

Associated language elements

delay force promise?

Input/Output

LispMe now supports input/output of MemoPad memos via the standard Scheme port mechanism. The first line in a memo is treated as the memo's "file name". At most 16 characters of this file name are significant when searching or creating memos. The file name is case-sensitive. Opening a memo with open-append-file or open-output-file creates an output port, which can be used as an optional parameter to display and write. No more than 4096 chars (the current MemoPad limit) can be output. New memos are always created in the category unfiled. Calling open-output-file with the name of an existing memo just creates another memo with the same name and does not overwrite the existing one.

You can open an existing memo for reading with open-input-file, which returns an input port to be used with read, read-char, read-line, or peek-char. It's possible to open several input ports for the same memo; each port maintain its own read position.

LispMe ports don't need to be closed, so there are no procedures close-input-port or close-output-port. Additionally, MemoPad IO is quite robust, you can even delete a memo when a port is open without risking crashes!

LispMe provides other procedures, which read input from popup dialogs (the parameter is displayed as a prompt text in each case) and write output to the output field.

Additionally, there's a procedure wait-pen, which waits for a pen tap and returns the coordinates of the pen as a pair.

Associated language elements

delete-file dir display eof_object? error
input input-port? input-string message newline
open-append-file open-input-file open-output-file output-port? peek-char
port? read read-char read-line wait-pen
write

Graphics

LispMe has limited graphics support. There's no special screen or window where graphic is output, but it is drawn into the output field. The graphic output remains until the output field is redrawn by a text output operation like write or the REP loop.

The graphic routines use device coordinates in the range (0,0) to (159,87). (0,0) corresponds to the upper left corner of the output field, which is in fact 17 pixels below screen coordinates (0,0). Remember this when using the coordinates returned by wait-pen, which are screen coordinates.

Drawing attributes like color, font and pattern are controlled via global variables. These variables are bound to fixed cells at LispMe startup, so you should never modify them with set!. Instead, use set-car! or set-cdr! to modify their components.

Associated language elements

*font* *pat* *point* draw rect text

LispMe extensions at a glance

The following constants, variables and procedures are not defined in R4RS.
#n *font* *pat* *point* acosh
asinh atanh cosh delete-file dir
disasm draw error eval gensym
input input-string integer it log10
macro macro? none? message object->string
open-append-file random read-line rect sinh
sound string->object tanh text wait
wait-pen