home *** CD-ROM | disk | FTP | other *** search
- This document describes features non-standard or peculiar to my
- implementation of scheme and assumes that you have loaded the
- following files into the interpreter: init.scm, extra.scm, and
- macros.scm (the shell script fl performs part of this task).
-
- notation:
-
- Square brackets indicate an optional argument. The ... notation
- means zero or more of the preceding argument/form.
-
- special forms:
-
- (extend-syntax (name key ...) (pattern [fender] expansion) ...)
- Eugene Kohlbecker's extend-syntax. Kent Dybvig wrote the
- implementation.
- (unless test expr ...)
- Evalutate the exprs only if test evaluates to #f.
- (when test expr ...)
- Evalutate the exprs only if test does not evalutate to #f.
- (do ((var init [step]) ...) (test expr1 ...) expr2 ...)
- Evaluate the expr2s in the scope of the variable vars until
- test evaluates to true. The vars take on the value of step
- after each iteration (or stay the same if no step was specified).
- The do form evaluates to the value of the last expr1.
- (case key ((datum ...) expr ...) ...)
- Evalutate the exprs of the first datum found to be eqv? to key.
- (record-case val (key idspec expr ...) ...)
- Evaluate the exprs of the key that matches the car of val.
- The exprs are evaluated in the scope of the pattern variables
- in idspec which are matched to the cdr of val.
- See "The Scheme Programming Language", by Kent Dybvig.
- (while test expr ...)
- Evaluate the exprs while test continues to evalutes to #t.
- (define-structure (name id1 ...) [((id2 val) ...)])
- Define a structure type called name with user initializable
- fields named after the id1s and automatically intialialized
- fields id2s (to val).
- define-structure defines the constructor (make-name id1 ...);
- the predicate (name? obj); and for each id1 and id2 an accessor
- and mutator: (name-field obj) and (set-name-field! obj val).
- From "The Scheme Programming Language".
- (the-environment)
- Evaluates to the current environment.
- (define-macro macro-name expander)
- Associate the procedure expander with macro-name. Before an
- expression is evaluatued, the evaluator applies the expander
- to the arguments of any form whose car is macro-name. See
- macros below.
-
- procedures:
-
- (ormap pred list ...)
- Apply pred to the items in list returning the first non-false
- result (or the last result if there were no previous true results).
- Pred must accept as many arguments as lists provided.
- (andmap pred list ...)
- Apply pred to the items in list returning the first false result
- (or the last result if there were no previous false results).
- Pred must accept as many arguments as lists provided.
- (trace proc)
- Trace calls to proc. Tail-recursive calls and exits are
- not traceable, because the proc may only be called once.
- (untrace proc)
- Stop tracing proc.
- (make-box obj)
- Create a pointer to obj. Literal boxes can be created by #&obj.
- Boxes are from "The Scheme Programming Language".
- (set-box! box obj)
- Change the value of pointer box to obj.
- (unbox box)
- Dereference the pointer box.
- (string->uninterned-symbol string)
- Create a symbol that is not eq? to any other symbol. Useful
- as identifiers in macros.
- (fprintf port format args ...)
- (printf format args ...)
- Prints the format string. The format string can contain embedded
- format specifiers:
- ~s - print arg using write
- ~a - print arg using display
- ~c - print character arg without #\ escape
- ~% - print a newline
- ~~ - print a tilde
- From "The Scheme Programming Language".
- (pretty-print expr [port])
- Pretty print expr to port or (current-output-port).
- If expr is a procedure, then its lambda body is printed
- instead (only if SAVE_LAMBDA_BODIES is defined in config.h).
- The pretty printer is loaded by (require 'pp).
- (pp expr|macro-name)
- Like pretty-print except if expr is a symbol, it is assumed
- to be a macro name and the body of the macro expander is pretty
- printed instead of the symbol.
- (in-package package-name)
- Change the current package to package-name.
- (require package-name)
- Load the package package-name if not already loaded. The name
- of the file to load is constructed by the package-name
- followed by the value of the variable *package-ext*, by default
- ".scm". The loader looks in the directories in the list
- *package-path*, by default ("./" "~/scm/" "/usr/local/lib/fools/"),
- for the file.
- (provide package-name)
- Changes the variable *packages* to reflect that the package has
- been loaded (checked by require).
- (package-environment package-name)
- Gets the environment of the package called package-name.
- (file-access file-name access-mode)
- Returns #t if file-name can be accessed according to access-mode
- which is a string of access characters: r - read; w - write;
- x - execute; or f - existence.
- See the UNIX man page for access(2).
- (file-open file-name rw-mode)
- Open file with mode rw-mode and return the corresponding file object.
- rw-mode is as specified in the UNIX man page for fopen(3).
- (file-close file)
- Close the file object.
- (file-tell file)
- Returns the current offset position within the file.
- (file-seek file offset offset-type)
- Changes the current offset position within the file to offset
- bytes from the beginning, current posiition, or end of the file
- depending on whether offset-type is #\b, #\c, or #\e respectively.
- (eval expr environment)
- Evaluate expr in environment.
- (code-body proc)
- Returns the lambda expression for proc. Note that this is only
- true if the compile option SAVE_LAMBDA_BODIES was defined
- in config.h.
- (macro macro-name)
- Get the expander associatiated with macro-name.
- (abort) Abort the current evaluation.
- (exit) Exit from the interpreter.
-
- notes:
-
- Square brackets can be used instead of parentheses for list syntax.
- Curly braces can be used instead of #( and ) for vector syntax.
- Evaluating the empty combination, (), does not produce an error.
- Vector #(...) and box #&... literals evaluate to themselves.
- #f is the empty list (see config.h about how to make #f unique).
- Altering constants with mutation operators does not produce an error.
- if returns #f if no else clause was specified.
- apply is not available as a procedure but allows tail recursion.
- String manipulation routines (except string-set!) work on symbols.
- Only double precision floating point and long integers are supported.
- Most of the number syntax and exactness is not implemented.
-
- packages:
-
- Fools' lisp packages are similar to packages in Common Lisp. A
- definition in a package is accessed by preceding the identifier of
- the definition with the name of the package. (foo:bar 1 2) calls the
- function bar defined in package foo with the arguments 1 and 2.
-
- Packages are loaded by the require procedure. For example, (require 'pp)
- loads the pretty printer.
-
- Internally, packages are represented by environments. The environment
- for a package is obtained by the package-environment procedure. The
- scope of the package is similar to the scope of a lambda defined in
- the global environment: bindings made inside the package environment
- are not visible in the global environment although the bindings of the
- global environment are visible in the package.
-
- Semantically, package-name:identifier is equivalent to
- (eval 'identifier (package-environment 'package-name)).
-
- The evaluator has a notion of the current package. Expressions are
- evaluated in the environment of the current package. Initially, the
- current package is the package named top-level. Its environment is
- the global environment.
-
- The in-package procedure changes the current package. The load
- procedure saves and restores the current package around the load,
- so you can call load without worrying about whether the current
- package changes. A file can insure that it is loaded into a
- particular package by including as the first expression
- (in-package 'package-name).
- The provide procedure notes that a particular package has been loaded,
- so that subsequent require's will not cause the package to be reloaded.
- Often, a provide is the second expression, after an in-package, in a
- file.
-
- The Common LISP functions export and use-package are not implemented.
- As a result, no definition within a package can be hidden (so CL's
- package-name::identifier is unnecessary). There exists a kludge to
- export definitions. Identifiers in define and set! statements can
- include a package qualifier to determine where the binding is created.
- For example:
- (define top-level:foo (lambda (x) x))
- binds foo in the top-level package, although the lambda is defined
- within the current package. Since all packages can access the
- environment of the top-level, foo is still available to the current
- package. Chosing a package other than the top-level is not too useful.
-
- macros:
-
- Define-macro associates a symbol with a procedure that constructs the
- expansion. Before an expression of the form (symbol expr ...) is
- evaluated, it is macro expanded if an expander is associated with the
- symbol. The expander is applied to the arguments of the expression.
- The result becomes the new expression. Short circuiting occurs if the
- expander returns an expression that is the same form (i.e., the macro
- would be applied to the form again).
-
- The (define (func arg) body) syntax is layered over the define special
- form as a macro:
-
- (define-macro define
- (lambda (sym . body)
- (if (pair? sym)
- `(define ,(car sym) (lambda ,(cdr sym) ,@body))
- `(define ,sym ,@body))))
-
- A macro for + can combine constants:
-
- (define-macro +
- (lambda args
- (let ([constants (filter number? args)]
- [exprs (filter (lambda (x) (not (number? x))) args)])
- (cond [(null? constants)
- `(+ ,@exprs)]
- [(null? exprs)
- (reduce + constants 0)]
- [else
- `(+ ,@exprs ,(reduce + constants 0))]))))
-
- Note that macros are currently expanded top down, so sub-expressions
- that evaluate to constants will not be spotted by this macro, e.g.,
- (macro-expand '(+ (+ 2 4) 3)) yields (+ 6 3).
-
- Because macros are expanded before evaluation, they must be defined
- before they appear in the program. Redefining a macro has no effect
- on previously defined forms. Macros are also globally visible.
-
- The procedure macro-expand returns its argument expanded. This is
- useful for debugging macros. Currently, forms, such as lambda, are
- not fully expanded. A second step before evaluation, preprocesses
- (and macro expands) all lambda forms.
-
- suggested reading:
-
- The Structure and Interpretation of Computer Programs
- H. Ableson, G.J. Sussman
- The Scheme Programming Language
- R. Kent Dybvig
- Revised^3 Report on the Algorithmic Language Scheme
- J. Rees, W. Clinger, et al.
-