source: project/wiki/Non standard macros and special forms @ 2905

Last change on this file since 2905 was 2905, checked in by felix winkelmann, 14 years ago

manual updates

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