source: project/chicken/trunk/manual/Non-standard macros and special forms @ 15794

Last change on this file since 15794 was 15794, checked in by felix winkelmann, 10 years ago

documented reexport; added test

File size: 17.9 KB
Line 
1[[tags: manual]]
2
3[[toc:]]
4
5== Non-standard macros and special forms
6
7=== Making extra libraries and extensions available
8
9==== require-library
10
11 [syntax] (require-library ID ...)
12
13This form does all the necessary steps to make the libraries or extensions given
14in {{ID ...}} available. It loads syntactic extensions, if needed and generates
15code for loading/linking with core library modules or separately installed
16extensions.
17
18During interpretation/evaluation {{require-library}} performs one of the
19following:
20
21* 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.
22* If {{ID}} names one of the syntactic extensions {{chicken-syntax chicken-ffi-syntax}}, then this extension will be loaded.
23* If {{ID}} names one of the core library units shipped with CHICKEN, then a {{(load-library 'ID)}} will be performed.
24* 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.
25* Otherwise, {{(require-library ID)}} is equivalent to {{(require 'ID)}}.
26
27During compilation, one of the following happens instead:
28
29* 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.
30* 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.
31* 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.
32* 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.
33* Otherwise {{(require-library ID)}} is equivalent to {{(require 'ID)}}.
34
35To make long matters short - just use {{require-library}} and it will normally figure everything out for dynamically
36loadable extensions and core library units.
37
38{{ID}} should be a pure extension name and should not contain any path prefixes (for example {{dir/lib...}}) is illegal).
39
40{{ID}} may also be a list that designates an extension-specifier. Currently the following extension specifiers are
41defined:
42
43* {{(srfi NUMBER ...)}} is required for SRFI-55 compatibility and is fully implemented
44* {{(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>=?}}).
45
46See also: {{set-extension-specifier!}}
47
48==== require-extension
49
50 [syntax] (require-extension ID ...)
51
52This is equivalent to {{(require-library ID ...)}} but performs an implicit
53{{import}}.
54This implementation of {{require-extension}} is compliant with [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]]
55(see the [[http://srfi.schemers.org/srfi-55/srfi-55.html|SRFI-55]] document for more information).
56
57==== use
58
59 [syntax] (use ID ...)
60
61{{use}} is just a shorter alias for {{require-extension}}.
62
63
64=== Binding forms for optional arguments
65
66==== optional
67
68 [syntax] (optional ARGS DEFAULT)
69
70Use this form for procedures that take a single optional argument. If
71{{ARGS}} is the empty list {{DEFAULT}} is evaluated and
72returned, otherwise the first element of the list {{ARGS}}. It is
73an error if {{ARGS}} contains more than one value.
74
75<enscript highlight=scheme>
76(define (incr x . i) (+ x (optional i 1)))
77(incr 10)                                   ==> 11
78(incr 12 5)                                 ==> 17
79</enscript>
80==== case-lambda
81
82 [syntax] (case-lambda (LAMBDA-LIST1 EXP1 ...) ...)
83
84Expands into a lambda that invokes the body following the first
85matching lambda-list.
86
87<enscript highlight=scheme>
88(define plus
89  (case-lambda
90    (() 0)
91    ((x) x)
92    ((x y) (+ x y))
93    ((x y z) (+ (+ x y) z))
94    (args (apply + args))))
95
96(plus)                      ==> 0
97(plus 1)                    ==> 1
98(plus 1 2 3)                ==> 6
99</enscript>
100
101For more information see the documentation for
102[[http://srfi.schemers.org/srfi-16/srfi-16.html|SRFI-16]]
103
104==== let-optionals
105
106 [syntax]  (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...)
107
108Binding constructs for optional procedure arguments. {{ARGS}} should
109be a rest-parameter taken from a lambda-list. {{let-optionals}}
110binds {{VAR1 ...}} to available arguments in parallel, or
111to {{DEFAULT1 ...}} if not enough arguments were provided.
112{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every
113variable sees the previous ones. it is an error if any excess
114arguments are provided.
115
116<enscript highlight=scheme>
117(let-optionals '(one two) ((a 1) (b 2) (c 3))
118  (list a b c) )                               ==> (one two 3)
119</enscript>
120
121==== let-optionals*
122
123 [syntax]  (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)
124
125Binding constructs for optional procedure arguments. {{ARGS}} should
126be a rest-parameter taken from a lambda-list. {{let-optionals}}
127binds {{VAR1 ...}} to available arguments in parallel, or
128to {{DEFAULT1 ...}} if not enough arguments were provided.
129{{let-optionals*}} binds {{VAR1 ...}} sequentially, so every
130variable sees the previous ones. If a single variable {{RESTVAR}}
131is given, then it is bound to any remaining arguments, otherwise it is
132an error if any excess arguments are provided.
133
134<enscript highlight=scheme>
135(let-optionals* '(one two) ((a 1) (b 2) (c a))
136  (list a b c) )                               ==> (one two one)
137</enscript>
138
139
140=== Other binding forms
141
142==== and-let*
143
144 [syntax] (and-let* (BINDING ...) EXP1 EXP2 ...)
145
146SRFI-2. Bind sequentially and execute body. {{BINDING}} can
147be a list of a variable and an expression, a list with a single
148expression, or a single variable. If the value of an expression
149bound to a variable is {{#f}}, the {{and-let*}} form
150evaluates to {{#f}} (and the subsequent bindings and the body
151are not executed).  Otherwise the next binding is performed. If
152all bindings/expressions evaluate to a true result, the body is
153executed normally and the result of the last expression is the
154result of the {{and-let*}} form. See also the documentation for
155[[http://srfi.schemers.org/srfi-2/srfi-2.html|SRFI-2]].
156
157==== rec
158
159 [syntax] (rec NAME EXPRESSION)
160 [syntax] (rec (NAME VARIABLE ...) BODY ...)
161
162Allows simple definition of recursive definitions. {{(rec NAME EXPRESSION)}} is
163equivalent to {{(letrec ((NAME EXPRESSION)) NAME)}} and {{(rec (NAME VARIABLE ...) BODY ...)}}
164is the same as {{(letrec ((NAME (lambda (VARIABLE ...) BODY ...))) NAME)}}.
165
166==== cut
167
168 [syntax] (cut SLOT ...)
169 [syntax] (cute SLOT ...)
170
171[[http://srfi.schemers.org/srfi-26/srfi-26.html|Syntactic sugar for specializing parameters]].
172
173==== define-values
174
175 [syntax] (define-values (NAME ...) EXP)
176
177Defines several variables at once, with the result values of expression
178{{EXP}}.
179
180==== fluid-let
181
182 [syntax] (fluid-let ((VAR1 X1) ...) BODY ...)
183
184Binds the variables {{VAR1 ...}} dynamically to the values {{X1 ...}}
185during execution of {{BODY ...}}.
186
187==== let-values
188
189 [syntax] (let-values (((NAME ...) EXP) ...) BODY ...)
190
191Binds multiple variables to the result values of {{EXP ...}}.
192All variables are bound simultaneously.
193
194==== let*-values
195
196 [syntax] (let*-values (((NAME ...) EXP) ...) BODY ...)
197
198Binds multiple variables to the result values of {{EXP ...}}.
199The variables are bound sequentially.
200
201<enscript highlight=scheme>
202(let*-values (((a b) (values 2 3))
203              ((p) (+ a b)) )
204  p)                               ==> 5
205</enscript>
206
207==== letrec-values
208
209 [syntax] (letrec-values (((NAME ...) EXP) ...) BODY ...)
210
211Binds the result values of {{EXP ...}} to multiple variables at once.
212All variables are mutually recursive.
213
214<enscript highlight=scheme>
215(letrec-values (((odd even)
216                   (values
217                     (lambda (n) (if (zero? n) #f (even (sub1 n))))
218                     (lambda (n) (if (zero? n) #t (odd (sub1 n)))) ) ) )
219  (odd 17) )                           ==> #t
220</enscript>
221
222==== parameterize
223
224 [syntax] (parameterize ((PARAMETER1 X1) ...) BODY ...)
225
226Binds the parameters {{PARAMETER1 ...}} dynamically to the values
227{{X1 ...}} during execution of {{BODY ...}}.  (see also:
228{{make-parameter}} in [[Parameters]]). Note that {{PARAMETER}} may be any
229expression that evaluates to a parameter procedure.
230
231==== receive
232
233 [syntax] (receive (NAME1 ... [. NAMEn]) VALUEEXP BODY ...)
234 [syntax] (receive VALUEEXP)
235
236SRFI-8. Syntactic sugar for {{call-with-values}}. Binds variables
237to the result values of {{VALUEEXP}} and evaluates {{BODY ...}}.
238
239The syntax
240
241<enscript highlight=scheme>
242(receive VALUEEXP)
243</enscript>
244
245is equivalent to
246
247<enscript highlight=scheme>
248(receive _ VALUEEXP _)
249</enscript>
250
251==== set!-values
252
253 [syntax] (set!-values (NAME ...) EXP)
254
255Assigns the result values of expression {{EXP}} to multiple
256variables.
257
258
259=== Substitution forms and macros
260
261==== define-constant
262
263 [syntax] (define-constant NAME CONST)
264
265Define a variable with a constant value, evaluated at compile-time.
266Any reference to such a
267constant should appear textually '''after''' its definition. This
268construct is equivalent to {{define}} when evaluated or interpreted.
269Constant definitions should only appear at toplevel. Note that constants
270are local to the current compilation unit and are not available outside
271of the source file in which they are defined. Names of constants still
272exist in the Scheme namespace and can be lexically shadowed.  If the
273value is mutable, then the compiler is careful to preserve its identity.
274{{CONST}} may be any constant expression, and may also refer to
275constants defined via {{define-constant}} previously.
276This for should only be used at top-level.
277
278==== define-inline
279
280 [syntax] (define-inline (NAME VAR ... [. VAR]) BODY ...)
281 [syntax] (define-inline NAME EXP)
282
283Defines an inline procedure. Any occurrence of {{NAME}} will be
284replaced by {{EXP}} or {{(lambda (VAR ... [. VAR]) BODY ...)}}.
285This is similar to a macro, but variable-names and -scope will
286be correctly handled.  Inline substitutions take place '''after'''
287macro-expansion.  {{EXP}} should be a lambda-expression. Any
288reference to {{NAME}} should appear textually '''after'''
289its definition. Note that inline procedures are local to the current
290compilation unit and are not available outside of the source file in
291which they are defined. Names of inline procedures still exist in the
292Scheme namespace and can be lexically shadowed.  This construct is
293equivalent to {{define}} when evaluated or interpreted. Inline
294definitions should only appear at toplevel.
295
296==== define-for-syntax
297
298 [syntax] (define-for-syntax (NAME VAR ... [. VAR]) EXP1 ...)
299 [syntax] (define-for-syntax NAME [VALUE])
300
301Defines the toplevel variable {{NAME}} at macro-expansion time. This can
302be helpful when you want to define support procedures for use in macro-transformers,
303for example.
304
305
306=== Conditional forms
307
308==== select
309
310 [syntax] (select EXP ((KEY ...) EXP1 ...) ... [(else EXPn ...)])
311
312This is similar to {{case}}, but the keys are evaluated.
313
314==== unless
315
316 [syntax] (unless TEST EXP1 EXP2 ...)
317
318Equivalent to:
319
320<enscript highlight=scheme>
321(if (not TEST) (begin EXP1 EXP2 ...))
322</enscript>
323
324==== when
325
326 [syntax] (when TEST EXP1 EXP2 ...)
327
328Equivalent to:
329
330<enscript highlight=scheme>
331(if TEST (begin EXP1 EXP2 ...))
332</enscript>
333
334
335=== Record structures
336
337==== define-record
338
339 [syntax] (define-record NAME SLOTNAME ...)
340
341Defines a record type. Call {{make-NAME}} to create an instance
342of the structure (with one initialization-argument for each slot).
343{{(NAME? STRUCT)}} tests any object for being an instance of this
344structure.  Slots are accessed via {{(NAME-SLOTNAME STRUCT)}}
345and updated using {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}.
346
347<enscript highlight=scheme>
348(define-record point x y)
349(define p1 (make-point 123 456))
350(point? p1)                      ==> #t
351(point-x p1)                     ==> 123
352(point-y-set! p1 99)
353(point-y p1)                     ==> 99
354</enscript>
355
356==== define-record-type
357
358 [syntax] (define-record-type NAME
359                              (CONSTRUCTOR TAG ...)
360                              PREDICATE
361                              (FIELD ACCESSOR [MODIFIER]) ...)
362
363SRFI-9 record types. For more information see the documentation for
364[[http://srfi.schemers.org/srfi-9/srfi-9.html|SRFI-9]].
365
366
367==== define-record-printer
368
369 [syntax] (define-record-printer (NAME RECORDVAR PORTVAR) BODY ...)
370 [syntax] (define-record-printer NAME PROCEDURE)
371
372Defines a printing method for record of the type {{NAME}} by
373associating a procedure with the record type. When a record of this
374type is written using {{display, write}} or {{print}}, then
375the procedure is called with two arguments: the record to be printed
376and an output-port.
377
378<enscript highlight=scheme>
379(define-record-type foo (make-foo x y z) foo?
380  (x foo-x)
381  (y foo-y)
382  (z foo-z))
383(define f (make-foo 1 2 3))
384(define-record-printer (foo x out)
385  (fprintf out "#,(foo ~S ~S ~S)"
386           (foo-x x) (foo-y x) (foo-z x)) )
387(define-reader-ctor 'foo make-foo)
388(define s (with-output-to-string
389              (lambda () (write f))))
390s                                   ==> "#,(foo 1 2 3)"
391(equal? f (with-input-from-string
392              s read)))             ==> #t
393</enscript>
394
395=== Other forms
396
397==== assert
398
399 [syntax] (assert EXP [STRING ARG ...])
400
401Signals an error if {{EXP}} evaluates to false. An optional message
402{{STRING}} and arguments {{ARG ...}} may be supplied to give a
403more informative error-message.  If compiled in ''unsafe'' mode (either
404by specifying the {{-unsafe}} compiler option or by declaring
405{{(unsafe)}}), then this expression expands to an unspecified value.
406The result is the value of {{EXP}}.
407
408
409==== begin-for-syntax
410
411 [syntax] (begin-for-syntax EXP ...)
412
413Equivalent to {{(begin EXP ...)}}, but performs the evaluation of
414the expression during macro-expansion time.
415
416
417==== cond-expand
418
419 [syntax] (cond-expand FEATURE-CLAUSE ...)
420
421Expands by selecting feature clauses. This form is allowed to appear in non-toplevel expressions.
422
423Predefined feature-identifiers are "situation" specific:
424
425; 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}}.
426
427; 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.
428
429; 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.
430
431The 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.
432
433In addition the following feature-identifiers may exist: {{applyhook}}, {{extraslot}}, {{ptables}}, {{dload}}.
434
435For further information, see the documentation for [[http://srfi.schemers.org/srfi-0/srfi-0.html|SRFI-0]].
436
437==== ensure
438
439 [syntax] (ensure PREDICATE EXP [ARGUMENTS ...])
440
441Evaluates the expression {{EXP}} and applies the one-argument
442procedure {{PREDICATE}} to the result. If the predicate returns
443{{#f}} an error is signaled, otherwise the result of {{EXP}}
444is returned.  If compiled in ''unsafe'' mode (either by specifying
445the {{-unsafe}} compiler option or by declaring {{(unsafe)}}),
446then this expression expands to an unspecified value.  If specified,
447the optional {{ARGUMENTS}} are used as arguments to the invocation
448of the error-signalling code, as in {{(error ARGUMENTS ...)}}. If
449no {{ARGUMENTS}} are given, a generic error message is displayed
450with the offending value and {{PREDICATE}} expression.
451
452==== eval-when
453
454 [syntax] (eval-when (SITUATION ...) EXP ...)
455
456Controls evaluation/compilation of subforms. {{SITUATION}} should
457be one of the symbols {{eval}}, {{compile}} or {{load}}.
458When encountered in the evaluator, and the situation specifier
459{{eval}} is not given, then this form is not evaluated and an
460unspecified value is returned.  When encountered while compiling code,
461and the situation specifier {{compile}} is given, then this form is
462evaluated at compile-time.  When encountered while compiling code, and the
463situation specifier {{load}} is not given, then this form is ignored
464and an expression resulting into an unspecified value is compiled instead.
465
466The following table should make this clearer:
467
468<table>
469<tr><th></th><th>In compiled code</th><th>In interpreted code</th></tr>
470<tr><td>{{eval}}</td><td>ignore</td><td>evaluate</td></tr>
471<tr><td>{{compile}}</td><td>evaluate at compile time</td><td>ignore</td></tr>
472<tr><td>{{load}}</td><td>compile as normal</td><td>ignore</td></tr>
473</table>
474
475==== include
476
477 [syntax] (include STRING)
478
479Include toplevel-expressions from the given source file in the currently
480compiled/interpreted program.  If the included file has the extension
481{{.scm}}, then it may be omitted.  The file is searched in the
482current directory and, if not found, in all directories specified in the
483{{-include-path}} option.
484
485==== nth-value
486
487 [syntax] (nth-value N EXP)
488
489Returns the {{N}}th value (counting from zero) of the values returned
490by expression {{EXP}}.
491
492==== time
493
494 [syntax] (time EXP1 ...)
495
496Evaluates {{EXP1 ...}} and prints elapsed time and some
497values about GC use, like time spent in major GCs, number of minor
498and major GCs.
499
500---
501Previous: [[Non-standard read syntax]]
502
503Next: [[Modules and macros]]
Note: See TracBrowser for help on using the repository browser.