File: define-syntax

package info (click to toggle)
scheme9 2025.08.12-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,080 kB
  • sloc: lisp: 16,752; ansic: 11,869; sh: 806; makefile: 237; sed: 6
file content (58 lines) | stat: -rw-r--r-- 2,135 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
R4RS Appendix  (define-syntax <keyword> <transformer>)     ==>  unspecific
S9fES          (define-syntax <symbol> <procedure>)        ==>  unspecific
S9fES          (define-syntax (<sym1> <sym2> ...) <body>)  ==>  unspecific

Syntax: The <keyword> is an identifier, and <transformer> should be
an instance of SYNTAX-RULES.

Semantics: The top-level syntactic environment is extended by binding
the <keyword> to the specified transformer.

(define-syntax let*
  (syntax-rules ()
    ((let* () body1 body2 ...)
     (let () body1 body2 ...))
    ((let* ((name1 val1) (name2 val2) ...)
       body1 body2 ...)
     (let ((name1 val1))
       (let* ((name2 val2) ...)
         body1 body2 ...)))))

In addition to the above the DEFINE-SYNTAX implementation of S9fES
allows to bind an ordinary procedure to a syntactic keyword. Its forms
are similar to those of DEFINE. The first form binds a <symbol> to a
<procedure>, which is specified as its second argument. The other form
binds <sym1> to the form

(lambda (<sym2> ...) <body>).

The procedures bound by DEFINE-SYNTAX may be variadic.

Procedures bound by DEFINE-SYNTAX are commonly called "macros". They
receive their arguments in textual (unevaluated) form and they are
called at macro expansion time, i.e. after reading a program but
before evaluating it. When an expression containing a macro application
is being expanded, the macro is applied to its arguments and the
application of the macro is replaced by the value returned by the
macro.

(define-syntax when
  (lambda (pred . conseq)
    `(if ,pred (begin ,@conseq))))

(when (= 1 1)
      (display "true")
      #t)               ==>  #t

Macros may not recurse directly, but they may implement recursion
internally using LETREC or by rewriting their own applications. The
following macro, for example, does not work, because D is undefined
in the body of D:

(define-syntax (d x) (and (pair? x) (d (cdr x)))) ; WRONG!

The following version does work, though, because the macro gets
rewritten to another application of itself, which is subsequently
being expanded:

(define-syntax (d x) (and (pair? x) `(d ,(cdr x)))) ; OK