[[tags: manual]]

[[toc:]]

== Non-standard macros and special forms

=== Making extra libraries and extensions available

==== require-library

<macro>(require-library ID ...)</macro>

This form does all the necessary steps to make the libraries or extensions given
in {{ID ...}} available. It loads syntactic extensions, if needed and generates
code for loading/linking with core library modules or separately installed
extensions.

During interpretation/evaluation {{require-library}} performs one of the
following:

* If {{ID}} names a built-in feature {{chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55}}, then nothing is done.
* If {{ID}} names one of the syntactic extensions {{chicken-syntax chicken-ffi-syntax}}, then this extension will be loaded.
* If {{ID}} names one of the core library units shipped with CHICKEN, then a {{(load-library 'ID)}} will be performed.
* If {{ID}} names an installed extension with the {{syntax}} or {{require-at-runtime}} attribute, then the extensions is loaded at compile-time, probably doing a run-time {{(require ...)}} for any run-time requirements.
* Otherwise, {{(require-library ID)}} is equivalent to {{(require 'ID)}}.

During compilation, one of the following happens instead:

* If {{ID}} names a built-in feature {{chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55}}, then nothing is done.
* If {{ID}} names one of the syntactic extensions {{chicken-syntax chicken-ffi-syntax}}, then this extension will be loaded at compile-time, making the syntactic extensions available in compiled code.
* If {{ID}} names one of the core library units shipped with CHICKEN, or if the option {{-uses ID}} has been passed to the compiler, then a {{(declare (uses ID))}} is generated.
* If {{ID}} names an installed extension with the {{syntax}} or {{require-at-runtime}} attribute, then the extension is loaded at compile-time, and code is emitted to {{(require ...)}} any needed run-time requirements.
* Otherwise {{(require-library ID)}} is equivalent to {{(require 'ID)}}.

To make long matters short - just use {{require-library}} and it will normally figure everything out for dynamically
loadable extensions and core library units.

{{ID}} should be a pure extension name and should not contain any path prefixes (for example {{dir/lib...}}) is illegal).

{{ID}} may also be a list that designates an extension-specifier. Currently the following extension specifiers are
defined:

* {{(srfi NUMBER ...)}} is required for SRFI-55 compatibility and is fully implemented
* {{(version ID NUMBER)}} is equivalent to {{ID}}, but checks at compile-time whether the extension named {{ID}} is installed and whether its version is equal or higher than {{NUMBER}}. {{NUMBER}} may be a string or a number, the comparison is done lexicographically (using {{string>=?}}).

See also: {{set-extension-specifier!}}

==== require-extension

<macro>(require-extension ID ...)</macro>

This is equivalent to {{(require-library ID ...)}} but performs an implicit
{{import}}, if necessary. {{ID}} may also be an import specification
(using {{rename}}, {{only}}, {{except}} or {{prefix}}).

This implementation of {{require-extension}} is compliant with [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]]
(see the [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]] document for more information).

==== use

<macro>(use ID ...)</macro>

{{use}} is just a shorter alias for {{require-extension}}.


=== Binding forms for optional arguments

==== optional

<macro>(optional ARGS DEFAULT)</macro>

Use this form for procedures that take a single optional argument. If
{{ARGS}} is the empty list {{DEFAULT}} is evaluated and
returned, otherwise the first element of the list {{ARGS}}. It is
an error if {{ARGS}} contains more than one value.

<enscript highlight=scheme>
(define (incr x . i) (+ x (optional i 1)))
(incr 10)                                   ==> 11
(incr 12 5)                                 ==> 17
</enscript>
==== case-lambda

<macro>(case-lambda (LAMBDA-LIST1 EXP1 ...) ...)</macro>

Expands into a lambda that invokes the body following the first
matching lambda-list.

<enscript highlight=scheme>
(define plus
  (case-lambda 
    (() 0)
    ((x) x)
    ((x y) (+ x y))
    ((x y z) (+ (+ x y) z))
    (args (apply + args))))

(plus)                      ==> 0
(plus 1)                    ==> 1
(plus 1 2 3)                ==> 6
</enscript>

For more information see the documentation for
[[http://srfi.schemers.org/srfi-16/srfi-16.html|SRFI-16]]

==== let-optionals

<macro> (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...)</macro>

Binding constructs for optional procedure arguments. {{ARGS}} should
be a rest-parameter taken from a lambda-list. {{let-optionals}}
binds {{VAR1 ...}} to available arguments in parallel, or
to {{DEFAULT1 ...}} if not enough arguments were provided.
{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every
variable sees the previous ones. it is an error if any excess
arguments are provided.

<enscript highlight=scheme>
(let-optionals '(one two) ((a 1) (b 2) (c 3))
  (list a b c) )                               ==> (one two 3)
</enscript>

==== let-optionals*

<macro> (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)</macro>

Binding constructs for optional procedure arguments. {{ARGS}} should
be a rest-parameter taken from a lambda-list. {{let-optionals}}
binds {{VAR1 ...}} to available arguments in parallel, or
to {{DEFAULT1 ...}} if not enough arguments were provided.
{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every
variable sees the previous ones. If a single variable {{RESTVAR}}
is given, then it is bound to any remaining arguments, otherwise it is
an error if any excess arguments are provided.

<enscript highlight=scheme>
(let-optionals* '(one two) ((a 1) (b 2) (c a))
  (list a b c) )                               ==> (one two one)
</enscript>


=== Other binding forms

==== and-let*

<macro>(and-let* (BINDING ...) EXP1 EXP2 ...)</macro>

SRFI-2. Bind sequentially and execute body. {{BINDING}} can
be a list of a variable and an expression, a list with a single
expression, or a single variable. If the value of an expression
bound to a variable is {{#f}}, the {{and-let*}} form
evaluates to {{#f}} (and the subsequent bindings and the body
are not executed).  Otherwise the next binding is performed. If
all bindings/expressions evaluate to a true result, the body is
executed normally and the result of the last expression is the
result of the {{and-let*}} form. See also the documentation for
[[http://srfi.schemers.org/srfi-2/srfi-2.html|SRFI-2]].

==== rec

<macro>(rec NAME EXPRESSION)</macro><br>
<macro>(rec (NAME VARIABLE ...) BODY ...)</macro>

Allows simple definition of recursive definitions. {{(rec NAME EXPRESSION)}} is
equivalent to {{(letrec ((NAME EXPRESSION)) NAME)}} and {{(rec (NAME VARIABLE ...) BODY ...)}}
is the same as {{(letrec ((NAME (lambda (VARIABLE ...) BODY ...))) NAME)}}.

==== cut

<macro>(cut SLOT ...)</macro><br>
<macro>(cute SLOT ...)</macro>

[[http://srfi.schemers.org/srfi-26/srfi-26.html|Syntactic sugar for specializing parameters]].

==== define-values

<macro>(define-values (NAME ...) EXP)</macro>

Defines several variables at once, with the result values of expression
{{EXP}}.

==== fluid-let

<macro>(fluid-let ((VAR1 X1) ...) BODY ...)</macro>

Binds the variables {{VAR1 ...}} dynamically to the values {{X1 ...}} 
during execution of {{BODY ...}}.

==== let-values

<macro>(let-values (((NAME ...) EXP) ...) BODY ...)</macro>

SRFI 11.  Binds multiple variables to the result values of {{EXP ...}}.
All variables are bound simultaneously.

==== let*-values

<macro>(let*-values (((NAME ...) EXP) ...) BODY ...)</macro>

SRFI 11.  Binds multiple variables to the result values of {{EXP ...}}.
The variables are bound sequentially.

<enscript highlight=scheme>
(let*-values (((a b) (values 2 3))
              ((p) (+ a b)) )
  p)                               ==> 5
</enscript>

==== letrec-values

<macro>(letrec-values (((NAME ...) EXP) ...) BODY ...)</macro>

Binds the result values of {{EXP ...}} to multiple variables at once.
All variables are mutually recursive.

<enscript highlight=scheme>
(letrec-values (((odd even)
                   (values 
                     (lambda (n) (if (zero? n) #f (even (sub1 n))))
                     (lambda (n) (if (zero? n) #t (odd (sub1 n)))) ) ) )
  (odd 17) )                           ==> #t
</enscript>

==== parameterize

<macro>(parameterize ((PARAMETER1 X1) ...) BODY ...)</macro>

Binds the parameters {{PARAMETER1 ...}} dynamically to the values
{{X1 ...}} during execution of {{BODY ...}}.  (see also:
{{make-parameter}} in [[Parameters]]). Note that {{PARAMETER}} may be any
expression that evaluates to a parameter procedure.

==== receive

<macro>(receive (NAME ...) VALUEEXP BODY ...)</macro><br>
<macro>(receive (NAME1 ... NAMEn . NAMEn+1) VALUEEXP BODY ...)</macro><br>
<macro>(receive VALUEEXP)</macro>

SRFI-8. Syntactic sugar for {{call-with-values}}. Binds variables
to the result values of {{VALUEEXP}} and evaluates {{BODY ...}}.

{{(receive VALUEEXP)}} is equivalent to {{(receive _ VALUEEXP _)}}.

==== set!-values

<macro>(set!-values (NAME ...) EXP)</macro>

Assigns the result values of expression {{EXP}} to multiple
variables.

=== Substitution forms and macros

==== define-constant

<macro>(define-constant NAME CONST)</macro>

Define a variable with a constant value, evaluated at compile-time. 
Any reference to such a
constant should appear textually '''after''' its definition. This
construct is equivalent to {{define}} when evaluated or interpreted.
Constant definitions should only appear at toplevel. Note that constants
are local to the current compilation unit and are not available outside
of the source file in which they are defined. Names of constants still
exist in the Scheme namespace and can be lexically shadowed.  If the
value is mutable, then the compiler is careful to preserve its identity.
{{CONST}} may be any constant expression, and may also refer to
constants defined via {{define-constant}} previously.
This for should only be used at top-level.

==== define-inline

<macro>(define-inline (NAME VAR ...) BODY ...)</macro><br>
<macro>(define-inline (NAME VAR1 ... VARn . VARn+1) BODY ...)</macro><br>
<macro>(define-inline NAME EXP)</macro>

Defines an inline procedure. Any occurrence of {{NAME}} will be
replaced by {{EXP}} or {{(lambda (VAR ... [. VAR]) BODY ...)}}. 
This is similar to a macro, but variable-names and -scope will
be correctly handled.  Inline substitutions take place '''after'''
macro-expansion.  {{EXP}} should be a lambda-expression. Any
reference to {{NAME}} should appear textually '''after'''
its definition. Note that inline procedures are local to the current
compilation unit and are not available outside of the source file in
which they are defined. Names of inline procedures still exist in the
Scheme namespace and can be lexically shadowed.  This construct is
equivalent to {{define}} when evaluated or interpreted. Inline
definitions should only appear at toplevel.

==== define-for-syntax

<macro>(define-for-syntax (NAME VAR ...) EXP1 ...)</macro><br>
<macro>(define-for-syntax (NAME VAR1 ... VARn . VARn+1) EXP1 ...)</macro><br>
<macro>(define-for-syntax NAME [VALUE])</macro>

Defines the toplevel variable {{NAME}} at macro-expansion time. This can
be helpful when you want to define support procedures for use in macro-transformers,
for example.


==== define-compiler-syntax

<macro>(define-compiler-syntax NAME)</macro><br>
<macro>(define-compiler-syntax NAME TRANSFORMER)</macro><br>
<macro>(define-compiler-syntax (NAME VAR ...) BODY ...)</macro>

Defines what is usually called a ''compiler macro'' in Lisp: {{NAME}} should be the
name of a globally or locally bound procedure. Any direct call to this procedure
will be transformed before compilation, which allows arbitrary rewritings
of function calls. 

{{TRANSFORMER}} can be a {{syntax-rules}} expression or an explicit-renaming transforme
procedure. Returning the original form in an explicit-renaming macro or simply
"falling trough" all patterns in a {{syntax-rules}} form will keep the original
expression and compile it normally.

In the interpreter this form does nothing and returns an unspecified value.

Compiler-syntax is always local to the current compilation unit and can not be
exported. Compiler-syntax defined inside a module is not visible outside of that
module.

{{define-compiler-syntax}} should only be used at top-level. Local compiler-syntax
can be defined with {{let-compiler-syntax}}.

<scheme>
(define-compiler-syntax +
  (syntax-rules ()
    ((_) 1)
    ((_ x 0) x) ) )
</scheme>

If no transformer is given, then {{(define-compiler-syntax NAME)}} removes
any compiler-syntax definitions for {{NAME}}.


==== let-compiler-syntax

<macro>(let-compiler-syntax ((NAME [TRANSFORMER]) ...) BODY ...)</macro>

Allows definition local compiler macros, which are only applicable inside {{BODY ...}}.
By not providing a transformer expression, compiler-syntax for specific identifiers
can be temporarily disabled.


=== Conditional forms

==== select

<macro>(select EXP ((KEY ...) EXP1 ...) ... [(else EXPn ...)])</macro>

This is similar to {{case}}, but the keys are evaluated.

==== unless

<macro>(unless TEST EXP1 EXP2 ...)</macro>

Equivalent to:

<enscript highlight=scheme>
(if (not TEST) (begin EXP1 EXP2 ...))
</enscript>

==== when

<macro>(when TEST EXP1 EXP2 ...)</macro>

Equivalent to:

<enscript highlight=scheme>
(if TEST (begin EXP1 EXP2 ...))
</enscript>


=== Record structures

==== define-record

<macro>(define-record NAME SLOTNAME ...)</macro>

Defines a record type. Call {{make-NAME}} to create an instance
of the structure (with one initialization-argument for each slot).
{{(NAME? STRUCT)}} tests any object for being an instance of this
structure.  Slots are accessed via {{(NAME-SLOTNAME STRUCT)}}
and updated using {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}.

<enscript highlight=scheme>
(define-record point x y)
(define p1 (make-point 123 456))
(point? p1)                      ==> #t
(point-x p1)                     ==> 123
(point-y-set! p1 99)
(point-y p1)                     ==> 99
</enscript>

==== define-record-type

<macro>(define-record-type NAME (CONSTRUCTOR TAG ...) PREDICATE (FIELD ACCESSOR [MODIFIER]) ...)</macro>

SRFI-9 record types. For more information see the documentation for
[[http://srfi.schemers.org/srfi-9/srfi-9.html|SRFI-9]].

As an extension the {{MODIFIER}} may have the form {{(setter PROCEDURE)}},
which will define a SRFI-17 setter-procedure for the given {{PROCEDURE}}
that sets the field value. Usually {{PROCEDURE}} has the same name
is {{ACCESSOR}} (but it doesn't have to).


==== define-record-printer

<macro>(define-record-printer (NAME RECORDVAR PORTVAR) BODY ...)</macro><br>
<macro>(define-record-printer NAME PROCEDURE)</macro>

Defines a printing method for record of the type {{NAME}} by
associating a procedure with the record type. When a record of this
type is written using {{display, write}} or {{print}}, then
the procedure is called with two arguments: the record to be printed
and an output-port.

<enscript highlight=scheme>
(define-record-type foo (make-foo x y z) foo?
  (x foo-x)
  (y foo-y)
  (z foo-z))
(define f (make-foo 1 2 3))
(define-record-printer (foo x out)
  (fprintf out "#,(foo ~S ~S ~S)"
           (foo-x x) (foo-y x) (foo-z x)) )
(define-reader-ctor 'foo make-foo)
(define s (with-output-to-string
              (lambda () (write f))))
s                                   ==> "#,(foo 1 2 3)"
(equal? f (with-input-from-string
              s read)))             ==> #t
</enscript>

=== Other forms

==== assert

<macro>(assert EXP [STRING ARG ...])</macro>

Signals an error if {{EXP}} evaluates to false. An optional message
{{STRING}} and arguments {{ARG ...}} may be supplied to give a
more informative error-message.  If compiled in ''unsafe'' mode (either
by specifying the {{-unsafe}} compiler option or by declaring
{{(unsafe)}}), then this expression expands to an unspecified value.
The result is the value of {{EXP}}.


==== begin-for-syntax

<macro>(begin-for-syntax EXP ...)</macro>

Equivalent to {{(begin EXP ...)}}, but performs the evaluation of
the expression during macro-expansion time.


==== cond-expand

<macro>(cond-expand FEATURE-CLAUSE ...)</macro>

Expands by selecting feature clauses. This form is allowed to appear in non-toplevel expressions.

Predefined feature-identifiers are "situation" specific:

; compile : {{eval}}, {{library}}, {{match}}, {{compiling}}, {{srfi-11}}, {{srfi-15}}, {{srfi-31}}, {{srfi-26}}, {{srfi-16}}, {{utils}}, {{regex}}, {{srfi-4}}, {{match}}, {{srfi-1}}, {{srfi-69}}, {{srfi-28}}, {{extras}}, {{srfi-8}}, {{srfi-6}}, {{srfi-2}}, {{srfi-0}}, {{srfi-10}}, {{srfi-9}}, {{srfi-55}}, {{srfi-61}} {{chicken}}, {{srfi-23}}, {{srfi-30}}, {{srfi-39}}, {{srfi-62}}, {{srfi-17}}, {{srfi-12}}.

; load : {{srfi-69}}, {{srfi-28}}, {{extras}}, {{srfi-8}}, {{srfi-6}}, {{srfi-2}}, {{srfi-0}}, {{srfi-10}}, {{srfi-9}}, {{srfi-55}}, {{srfi-61}}, {{chicken}}, {{srfi-23}}, {{srfi-30}}, {{srfi-39}}, {{srfi-62}}, {{srfi-17}}, {{srfi-12}}. {{library}} is implicit.

; eval : {{match}}, {{csi}}, {{srfi-11}}, {{srfi-15}}, {{srfi-31}}, {{srfi-26}}, {{srfi-16}}, {{srfi-69}}, {{srfi-28}}, {{extras}}, {{srfi-8}}, {{srfi-6}}, {{srfi-2}}, {{srfi-0}}, {{srfi-10}}, {{srfi-9}}, {{srfi-55}}, {{srfi-61}}, {{chicken}}, {{srfi-23}}, {{srfi-30}}, {{srfi-39}}, {{srfi-62}}, {{srfi-17}}, {{srfi-12}}. {{library}} is implicit.

The following feature-identifiers are available in all situations: {{(machine-byte-order)}}, {{(machine-type)}}, {{(software-type)}}, {{(software-version)}}, where the actual feature-identifier is platform dependent.

In addition the following feature-identifiers may exist: {{applyhook}}, {{extraslot}}, {{ptables}}, {{dload}}.

For further information, see the documentation for [[http://srfi.schemers.org/srfi-0/srfi-0.html|SRFI-0]].

==== ensure

<macro>(ensure PREDICATE EXP [ARGUMENTS ...])</macro>

Evaluates the expression {{EXP}} and applies the one-argument
procedure {{PREDICATE}} to the result. If the predicate returns
{{#f}} an error is signaled, otherwise the result of {{EXP}}
is returned.  If compiled in ''unsafe'' mode (either by specifying
the {{-unsafe}} compiler option or by declaring {{(unsafe)}}),
then this expression expands to an unspecified value.  If specified,
the optional {{ARGUMENTS}} are used as arguments to the invocation
of the error-signalling code, as in {{(error ARGUMENTS ...)}}. If
no {{ARGUMENTS}} are given, a generic error message is displayed
with the offending value and {{PREDICATE}} expression.

==== eval-when

<macro>(eval-when (SITUATION ...) EXP ...)</macro>

Controls evaluation/compilation of subforms. {{SITUATION}} should
be one of the symbols {{eval}}, {{compile}} or {{load}}.
When encountered in the evaluator, and the situation specifier
{{eval}} is not given, then this form is not evaluated and an
unspecified value is returned.  When encountered while compiling code,
and the situation specifier {{compile}} is given, then this form is
evaluated at compile-time.  When encountered while compiling code, and the
situation specifier {{load}} is not given, then this form is ignored
and an expression resulting into an unspecified value is compiled instead.

The following table should make this clearer:

<table>
<tr><th></th><th>In compiled code</th><th>In interpreted code</th></tr>
<tr><td>{{eval}}</td><td>ignore</td><td>evaluate</td></tr>
<tr><td>{{compile}}</td><td>evaluate at compile time</td><td>ignore</td></tr>
<tr><td>{{load}}</td><td>compile as normal</td><td>ignore</td></tr>
</table>

==== include

<macro>(include STRING)</macro>

Include toplevel-expressions from the given source file in the currently
compiled/interpreted program.  If the included file has the extension
{{.scm}}, then it may be omitted.  The file is searched in the
current directory and, if not found, in all directories specified in the
{{-include-path}} option.

==== nth-value

<macro>(nth-value N EXP)</macro>

Returns the {{N}}th value (counting from zero) of the values returned
by expression {{EXP}}.

==== time

<macro>(time EXP1 ...)</macro>

Performs a major garbage collection, evaluates {{EXP1 ...}} and prints
elapsed CPU time and some values about GC use, like time spent in major
GCs, number of minor and major GCs. The output is sent to the port
that is the current value of {{(current-error-port)}}. Nested invocations
of this form will give incorrect results for all output but the innermost.

---
Previous: [[Non-standard read syntax]]

Next: [[Macros]]
