(class-asi superclass clauses ...) (syntax)
Like class, but the initialization arguments are automatically passed on to the superclass initialization procedure.
(class-asi* superclasses clauses ...) (syntax)
Like class*, but the initialization arguments are automatically passed on to each superclass initialization procedure.
(catch-errors err-display err-result body ...) (syntax)
In the absence of run-time errors, the result of a catch-errors expression is the result of body. If an error is encountered during the evaluation of body, err-display is invoked as the error display handler and the result of the catch-errors expression is the result of applying the thunk err-result. If err-display is #f, then the current error display handler is used instead.
(define-struct-tree root (field ...) sub-struct ...) (syntax)
Each sub-struct is of the form:
(name (field ...) sub-struct ...)
(where sub-struct is recursively defined).
The define-struct-tree form defines a tree of sub-typed structures. The sub-type relationship is specified by nesting; each sub-struct form defines an immediate sub-type of the enclosing type definition. (This eliminates the need for writing a parent name in multiple define-struct expressions.)
The root expression can be an identifier or an identifier-expression pair the form (name supertype), where supertype evaluates to a structure type value. In the latter case, all of the structure types defined by the define-struct-tree expression are sub-types of the supertype structure type.
The name identifiers and field identifiers are used to define structure procedures and type values as in a define-struct expression.
For example, this collection of structure definitions:
(define-struct expr (object)) (define-struct (scanned struct:expr) ()) (define-struct (token struct:scanned) (object type)) (define-struct (read struct:expr) ()) (define-struct (scalar struct:read) ()) (define-struct (symbol struct:scalar) ()) (define-struct (number struct:scalar) ()) (define-struct (sequence struct:read) (length)) (define-struct (list struct:sequence) ()) (define-struct (vector struct:sequence) ())can be written more concisely as:
(define-struct-tree expr (object)
(scanned ()
(token (object type)))
(read ()
(scalar ()
(symbol ())
(number ()))
(sequence (length)
(list ())
(vector ()))))
(define-virtual-struct name fields) (syntax)
Like define-struct, but no constructor is defined. A ``virtual'' structure type is instantiated only through subtypes.
(let+ clause body ...) (syntax)
A new binding construct that specifies scoping on a per-binding basis instead of a per-expression basis. It helps eliminate rightward-drift in programs. It looks a lot like let, except each clause has an additional keyword tag before the binding variables.
Each clause has one of the following forms:
The clauses bind left-to-right. Each id above can either be an
identifier or (values id
). In the latter case,
multiple values returned by the corresponding expression are bound to
the mulitple identifiers.
Examples:
(let+ ([val (values x y) (values 1 2)])
(list x y)) ; => (1 2)
(let ([x 1])
(let+ ([val x 3]
[val y x])
y)) ; => 3
(let-enumerate name-lists body ...) (syntax)
This is a let-form, but instead of name-value pairs, lists of names are specified. For each name list, the first name is bound to the constant 1, the second name is bound to 2, etc.
For example:
(let-enumerate ([FILE-OPEN
FILE-CLOSE
FILE-QUIT]
[EDIT-COPY
EDIT-CUT
EDIT-PASTE])
body)
Within body, FILE-OPEN is 1, FILE-CLOSE is 2, FILE-QUIT is 3, EDIT-COPY is 1, etc.
(local definitions body ...) (syntax)
This local syntax roughly simulates Rice Scheme's local syntax by expanding to (begin definition body ...). This expansion has slightly different semantics than Rice Scheme's local, but the result is always the same when definitions contains only define expressions that do not capture a continuation. No checks are performed on the structure of the local expression.
(make-spawner opts-list params body ...) (syntax)
Returns a procedure that spawns a new thread and global variable space when the procedure is applied. The procedure's formal arguments are specified by params and these are bound by the application in body. The body is evaluated in the new thread, so free variables in body that are not in params will refer to global variables in the new global variable space. The opt-list expression should return a list of symbols that are passed on to spawn-eval to set options in the spawned process.
(opt-lambda formals body ...) (syntax)
The opt-lambda form is like lambda, except that default values are assigned to parameters (C++-style). Default values are defined in the formals list by replacing an identifier id by [id default-value-expression]. If an identifier has a default value expression, then all (non-aggregate) identifiers after it must have default value expressions. A final aggregate identifier can be used as in lambda, but it cannot be given a default value. Each default value expression is evaluated only if it is needed. The environment of each default value expression includes the preceding parameters.
For example:
(define f
(opt-lambda (a [b (add1 a)] . c)
...))
Here, f is a function which takes at least one argument. If a second argument is specified, it is the value of b, otherwise b is (add1 a). If more than two arguments are specified, then the extra arguments are placed in a new list that is the value of c.
(define-some export-var-list body ...) (syntax)
This syntactic form makes it convenient to develop a library of functions with helper functions at the top level, and then package the library so that only some of the names are actually exported to the top-level. The define-some form is only useful at the top-level.
The body expression is any sequence of top-level expressions. Only the variables listed in export-var-list will actually be defined at the top-level (with the values they have at the end of body).
For example, if this is evaluated at the top-level:
(define-some (f)
(define f-helper-1
(lambda ...))
(define f-helper-2
(lambda ...))
(define f
(lambda ...)))
then f is defined, but f-helper-1 and f-helper-2 are visible only to f and themselves.
(recur name bindings body ...) (syntax)
This is equivalent to a named let: (let name bindings body).
(send* obj msg
... msg
) (syntax)
Calls multiple methods of obj (in the specified order).
Each msg
should have the form:
(name params ...)
where name is the method name. For example:
(send* edit (begin-edit-sequence)
(insert "Hello")
(insert #
is the same as
newline)
(end-edit-sequence))
(send edit begin-edit-sequence)
(send edit insert "Hello")
(send edit insert #
newline)
(send edit end-edit-sequence))