Changeset 32960 in project


Ignore:
Timestamp:
12/06/15 12:39:59 (5 years ago)
Author:
juergen
Message:

bindings 4.1 docu

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/bindings

    r32916 r32960  
    22[[toc:]]
    33
    4 == Procedural macros made easy with bindings
    5 
    6 The Scheme standard, R5RS, only provides declarative macros based on
    7 syntax-rules. They are easy to use, but rather limited. For example, you
    8 can only create hygienic macros, you have no control over the expansion
    9 process, in particular, you can't use local procedures to be evaluated at
    10 compile time. To overcome this limitations, R6RS offers syntax-case
    11 macros, but that's a mouthfull ...
    12 
    13 Fortunately, Chicken offers two versions of procedural macros, explicit
    14 and implicit renaming macros. They offer full flexibility without any
    15 limitations but are tedious to use.
    16 
    17 First, you must care to avoid variable capture with renaming, if you
    18 want hygienic macros, or you must decide which variables should be
    19 captured on purpose. Implicit renaming here helps a lot: You simply
    20 inject names which you want to be captured, the others are renamed
    21 automatically by the runtime system.
    22 
    23 Second, you must do the destructuring of the macro code by hand.
    24 Wouldn't it be nice, if this could be done automatically behind the
    25 scene as well?
    26 
    27 This library provides the means for this to happen, in particular, two
    28 binding routines, bind and bind-case. The former is a Scheme
    29 implementation of Common Lisp's destructuring-bind, the latter a
    30 case variant of the former, similar to the match macro of the matchable
    31 library.
    32 
    33 Based on those binding routines and implicit renaming, some
    34 macro-writing macros are defined, in paraticular, a hygienic procedural
    35 define-macro and a procedural version of syntax-rules, named
    36 macro-rules. The latter is almost as easy to use as syntax-rules, but
    37 much more powerfull. Here is its syntax
    38 
    39 <macro>(macro-rules sym ... (keyword ...) (pat (where fender ...) .. tpl) ....)</macro>
    40 
    41 Note the special use of dots here and below: Three dots are ellipses, as
    42 usual, i.e. the pattern on the left is repeated zero or more times, two
    43 dots, zero or one time, 4 dots one ore several times.
    44 
    45 This form can be used instead of syntax-rules in define-syntax,
    46 let-sytax and letrec-syntax, provided, you import it for-syntax.
    47 sym ... denote the injected symbols to break hygiene (if there is none,
    48 the constructed macro is hygienic). keyword ... and pat .... symbols are
    49 as in syntax-rules, fender ... are expressions on pattern variables
    50 which must pass for the pattern to match, and tpl .... are usually
    51 quasiquoted expressions.
    52 
    53 And here is the syntax of define-macro
    54 
    55 <macro>(define-macro (name . args) (where fender ...) .. xpr ....))</macro>
    56 
    57 Note, that only this hygienic form survived in this version 4.0 of
    58 the bindings library. To handle injected symbols or keywords use
    59 macro-rules. And note also, that you need to import-for-syntax bind in
    60 compiled code.
     4
     5== Destructuring sequence expressions with bindings
     6
     7Automatic destructuring of expressions is a handy feature, which can be
     8successfully used in writing procedural macros, for example. Some
     9programming languages use it extensively, in particular ML and its
     10descendents Haskell and Miranda. And Chicken offers an egg called
     11matchable, which does it as well.
     12
     13This library provides an alternative to matchable, a bunch of macros,
     14all starting with the bind prefix, and all being derived from bind and
     15related procedures.  They all destructure arbitrary mixtures of
     16(pseudo-) lists, vectors and strings, which match a pattern, and can be
     17easily enhanced, to accept other sequence types as well, arrays, for
     18example.
     19
     20The syntax of the fundamental bind macro is as follows
     21
     22<macro>(bind pat (where fender ...) .. seq xpr ....)</macro>
     23
     24Here, a pattern, pat, is a nested psudolist of (mostly) symbols, seq a
     25sequencce expression, i.e. a mixture of pseudolists, vectors and
     26strings, fender a check expression on pattern variables and xpr ....
     27constitute the body of the macro. Note the special use of dots here and
     28below: Three dots repeat the expression to the left zero or many times,
     29two dots zero or one times and four dots one or many times.
     30
     31This macro binds pattern variables, i.e. symbols of pat, to corresponding
     32sequenceds of seq, checks, if the fenders succeed and exectutes the body
     33in this context.
    6134
    6235The bind macro is patterned after Paul Graham's dbind, cf. his classic
     
    11083
    11184<enscript highlight=scheme>
    112   (destruc '(a (b . c) . d) 'seq)
     85(destruc '(a (b . c) . d) 'seq)
    11386</enscript>
    11487
     
    11689
    11790<enscript highlight=scheme>
    118   ((a (list-ref seq 0))
    119    ((#:g (list-ref seq 1)) (b (list-ref #:g 0)) (c (list-tail #:g 1)))
    120    (d (list-tail seq 2)))
     91((a (list-ref seq 0))
     92 ((#:g (list-ref seq 1)) (b (list-ref #:g 0)) (c (list-tail #:g 1)))
     93 (d (list-tail seq 2)))
    12194</enscript>
    12295
     
    12497
    12598<enscript highlight=scheme>
    126   (let ((a (list-ref seq 0))
    127         (#:g (list-ref seq 1))
    128         (d (list-tail seq 2)))
    129     (let ((b (list-ref #:g 0))
    130           (c (list-tail #:g 1)))
    131       body))
     99(let ((a (list-ref seq 0))
     100      (#:g (list-ref seq 1))
     101      (d (list-tail seq 2)))
     102  (let ((b (list-ref #:g 0))
     103        (c (list-tail #:g 1)))
     104    body))
    132105</enscript>
    133106 
    134107Note, that the destructuring procedures are local to this macro. This is
    135108necessary in Chicken for the macro to work, in particular in compiled
    136 code, unless you import them for-syntax. But since they are of no
    137 interest outside of the macro, local procedures are preferable.
     109code, unless you define them for-syntax, but that would implicitly
     110export them. But since they are of no interest outside of the macro,
     111local procedures are preferable.
    138112
    139113Note further, that ir-macro-transformer does all the necessary renaming
     
    159133
    160134Second, non-symbol literals, which don't bind anything, of course, but
    161 match only themselves. This and the length checks are treated simply by
    162 pairing them as well with check-routines in destruc but separating the
    163 pairs with leading symbol from those with leading nil or literal in
    164 dbind-ex. The former are bound with lets as in Graham's code, the
    165 latter's cadrs being evaluated before the recursive call to dbind-ex.
     135match only expressions evaluating to themselves. This and the length
     136checks are treated simply by pairing them as well with check-routines in
     137destruc but separating the pairs with leading symbol from those with
     138leading nil or literal in dbind-ex. The former are bound with lets as in
     139Graham's code, the latter's cadrs being evaluated before the recursive
     140call to dbind-ex.
    166141
    167142The last feature missing is fenders, which is important in particular
    168143for bind-case and can easily be implemented with a where clause: A
    169144pattern matches successfully if only each pattern variable can be bound
    170 and the where clause is satisfied. If the where clause doesn't pass, the
    171 next pattern is tried in bind-case or a bind-exception is signalled in
    172 bind.
    173 
    174 == Bindings
    175 
    176 Off course, automatic destructuring of expressions is not only of
    177 interest in macro writing. For example, the ML-family of programming
    178 languages is based on it. Therefore, this library provides a bunch of
    179 macros, all starting with the bind prefix, and all being derived from
    180 bind and related procedures. They all destructure arbitrary mixtures of
    181 (pseudo-) lists, vectors and strings, which match a pattern, and can be
    182 easily enhanced, to accept other sequence types as well, arrays, for
    183 example. Here, a pattern is a nested pseudolist of symbols.
    184 
    185 === The module basic-bindings
    186 
    187 ==== basic-bindings
    188 
    189 <procedure>(basic-bindings sym ..)</procedure>
     145and the checks as well as the where clause are satisfied. If the where
     146clause doesn't pass, the next pattern is tried in bind-case or a
     147bind-exception is signalled in bind.
     148
     149=== The module bindings
     150
     151==== bindings
     152
     153<procedure>(bindings sym ..)</procedure>
    190154
    191155documentation procedure. Shows the exported symbols and the syntax of
     
    194158====  bind
    195159
    196 <macro>(bind pat seq (where fender ...) .. xpr ....)</macro>
     160<macro>(bind pat (where fender ...) .. seq xpr ....)</macro>
    197161
    198162binds pattern variables of pat to subexpressions of seq and executes
    199163xpr .... in this context, provided all fenders return #t, if supplied.
    200164
    201 ====  bind-case
    202 
    203 <macro>(bind-case seq (pat (where fender ...) .. xpr ....) ....)</macro>
    204 
    205 Matches seq against a series of patterns and executes the body of the
    206 first matching pattern satisfying fenders (if given).
    207 
    208 ==== bind-exception
    209 
    210 <procedure>(bind-exception loc msg . args)</procedure>
    211 
    212 generates a composite condition of type (exn bind) with location loc,
    213 message msg and arguments args.
    214 
    215 ==== bind-exception-handler
    216 
    217 <procedure>(bind-exception-handler var)</procedure>
    218 
    219 exception-handler to be passed to the parameter
    220 current-exception-handler
    221 
    222 ==== signal-bind-exception
    223 
    224 <procedure>(signal-bind-exception loc msg arg ...)</procedure>
    225 
    226 signals a bind-exception, can be used instead of error.
    227 
    228 ==== bind-table-show
    229 
    230 <procedure>(bind-table-show)</procedure>
    231 
    232 prints the contents of the table
    233 
    234 ==== bind-table-add!
    235 
    236 <procedure>(bind-table-add! type? len ref tail)</procedure>
    237 
    238 adds a custom new list of sequence operators to the top of the table
    239 (in previous versions of the library named seq-length-ref-tail!)
    240 
    241 ==== bind-seq-length
    242 
    243 <procedure>(bind-seq-length seq)</procedure>
    244 
    245 returns the length of the generic sequence seq
    246 (previously named seq-length)
    247 
    248 ==== bind-seq-ref
    249 
    250 <procedure>(bind-seq-ref seq n)</procedure>
    251 
    252 returns the nth item of the generic sequence seq
    253 (preveiously named seq-ref)
    254 
    255 ==== bind-seq-tail
    256 
    257 <procedure>(bind-seq-tail seq n)</procedure>
    258 
    259 returns the tail of the generic sequence seq, starting at n
    260 (previously named seq-tail)
    261 
    262 ==== symbol-dispatcher
    263 
    264 <procedure>(symbol-dispatcher alist)</procedure>
    265 
    266 creates a documentation procedure as used in all modules
    267 of this library.
    268 
    269 ==== list-of
    270 
    271 <procedure>(list-of ok? ...)</procedure>
    272 
    273 returns a predicate which checks, if its list argument passes every
    274 predicate ok? ...
    275 
    276 ==== vector-of
    277 
    278 <procedure>(vector-of ok? ...)</procedure>
    279 
    280 returns a predicate which checks, if its vector argument passes every
    281 predicate ok? ...
    282 
    283 
    284 === The module macro-bindings
    285 
    286 ==== macro-bindings
    287 
    288 <procedure>(macro-bindings sym ..)</procedure>
    289 
    290 documentation procedure. Shows the exported symbols and the syntax of
    291 such an exported symbol, respectively.
    292 
    293 ==== macro-rules
    294 
    295 <macro>(macro-rules sym ... (keyword ...) (pat (where fender ...) .. tpl) ....)</macro>
    296 
    297 like syntax-rules, but the templates are usually quasiquote-expressions.
    298 Moreover, the symbols sym ... are injected, if there are any.
    299 
    300 Note, that non-symbol literals are accepted in  each pat and
    301 considered a match if they are equal to a corresponding literal in the
    302 macro-code.
    303 
    304 macro-rules must be imported for-syntax if used in the preprocessing
    305 phase of a macro evaluation. The same applies to bind and friends.
    306 
    307 ==== define-macro
    308 
    309 <macro>(define-macro (name . args) (where fender ...) .. xpr ....))</macro>
    310 
    311 generates a hygienic implicit-renaming macro, name.
    312 
    313 ==== macro-let
    314 
    315 <macro>(macro-let (((name . args) (where fender ...) .. xpr ...) ...) body ....)</macro>
    316 
    317 evaluates body ... in the context of parallel hygienic macros name ....
    318 
    319 ==== macro-letrec
    320 
    321 <macro>(macro-letrec (((name . args) (where fender ...) .. xpr ...) ...) body ....)</macro>
    322 
    323 evaluates body ... in the context of recursive hygienic macros name ....
    324 
    325 ==== once-only
    326 
    327 <macro>(once-only (x ...)  body ....)</macro>
    328 
    329 to be used in a macro-body to avoid side-effects.
    330 The arguments x ... are only evaluated once.
    331 once-only must be imported for-syntax.
    332 
    333 ==== with-gensyms
    334 
    335 <macro>(with-gensyms (x ...) . body)</macro>
    336 
    337 to be used in a macro body. Generates a list of gensyms x ...
    338 with-gensyms must be imported for-syntax.
    339 
    340 === The module more-bindings
    341 
    342 ==== more-bindings
    343 
    344 <procedure>(more-bindings sym ..)</procedure>
    345 
    346 documentation procedure. Shows the exported symbols and the syntax of
    347 such an exported symbol, respectively.
    348 
    349165==== bindable?
    350166
    351 <macro>(bindable? pat (where fender ...))</macro>
     167<macro>(bindable? pat (where fender ...) ..)</macro>
    352168
    353169returns a unary predicate which checks, if its sequence argument matches
     
    355171(the syntax is slightly changed for consistency).
    356172
     173====  bind-case
     174
     175<macro>(bind-case seq (pat (where fender ...) .. xpr ....) ....)</macro>
     176
     177Matches seq against a series of patterns and executes the body of the
     178first matching pattern satisfying fenders (if given).
     179
    357180==== bind-define
    358181
    359 <macro>(bind-define pat seq)</macro>
     182<macro>(bind-define pat (where fender ...) .. seq)</macro>
    360183
    361184defines pattern variables of pat with values matching subexpressions of seq in one go
     
    363186==== bind-set!
    364187
    365 <macro>(bind-set! pat seq)</macro>
     188<macro>(bind-set! pat (where fender ...) .. seq)</macro>
    366189
    367190sets symbols of pat to corresponding subexpressions of seq
     
    379202combination of lambda and bind, multiple pattern arguments
    380203
     204==== bind-case-lambda
     205
     206<macro>(bind-case-lambda (pat (where fender ...) .. xpr ....) ....)</macro>
     207
     208Combination of bind-case and lambda with one pattern argument
     209
     210==== bind-case-lambda*
     211
     212<macro>(bind-case-lambda* (pat (where fender ...) .. xpr ....) ....)</macro>
     213
     214Combination of bind-case and lambda with multiple pattern arguments
     215
    381216==== bind*
    382217
    383 <macro>(bind* loop pat seq xpr ....)</macro>
     218<macro>(bind* loop pat (where fender ...) .. seq xpr ....)</macro>
    384219
    385220named version of bind.
     
    388223==== bindrec
    389224
    390 <macro>(bindrec pat seq xpr ....)</macro>
     225<macro>(bindrec pat (where fender ...) .. seq xpr ....)</macro>
    391226
    392227bind pattern variables of pat to subsequences of seq recursively
     
    394229====  bind-let
    395230
    396 <macro>(bind-let loop .. ((pat seq) ...) xpr ....)</macro>
     231<macro>(bind-let loop .. ((pat (where fender ...) .. seq) ...) xpr ....)</macro>
    397232
    398233like let, named and unnamed, but binds patterns to sequence templates.  In the named case loop is bound to a one-parameter-procedure accessible in the body xpr ....
     
    400235==== bind-let*
    401236
    402 <macro>(bind-let* ((pat seq) ...) xpr ....)</macro>
     237<macro>(bind-let* ((pat (where fender ...) .. seq) ...) xpr ....)</macro>
    403238
    404239like let*, but binds patterns to sequence templates
     
    406241==== bind-letrec
    407242
    408 <macro>(bind-letrec ((pat seq) ...) xpr ....)</macro>
     243<macro>(bind-letrec ((pat (where fender ...) .. seq) ...) xpr ....)</macro>
    409244
    410245like letrec, but binds patterns to sequence templates
    411 
    412 ==== bind-case-lambda
    413 
    414 <macro>(bind-case-lambda (pat (where fender ...) .. xpr ....) ....)</macro>
    415 
    416 Combination of bind-case and lambda with one pattern argument
    417 
    418 ==== bind-case-lambda*
    419 
    420 <macro>(bind-case-lambda* (pat (where fender ...) .. xpr ....) ....)</macro>
    421 
    422 Combination of bind-case and lambda with multiple pattern arguments
    423246
    424247==== bind/cc
     
    429252context.
    430253
    431 === The module bindings
    432 
    433 This convenience module imports and reexports all the routines of the modules above.
    434 
    435 ==== bindings
    436 
    437 <procedure>(bindings sym ..)</procedure>
    438 
    439 documentation procedure. Shows the exported symbols and the syntax of
    440 such an exported symbol, respectively.
     254==== bind-exception
     255
     256<procedure>(bind-exception loc msg . args)</procedure>
     257
     258generates a composite condition of type (exn bind) with location loc,
     259message msg and arguments args.
     260
     261==== bind-exception-handler
     262
     263<procedure>(bind-exception-handler var)</procedure>
     264
     265exception-handler to be passed to the parameter
     266current-exception-handler
     267
     268==== signal-bind-exception
     269
     270<procedure>(signal-bind-exception loc msg arg ...)</procedure>
     271
     272signals a bind-exception, can be used instead of error.
     273
     274==== bind-table-show
     275
     276<procedure>(bind-table-show)</procedure>
     277
     278prints the contents of the table
     279
     280==== bind-table-add!
     281
     282<procedure>(bind-table-add! type? len ref tail)</procedure>
     283
     284adds a custom new list of sequence operators to the top of the table
     285(in previous versions of the library named seq-length-ref-tail!)
     286
     287==== bind-seq-length
     288
     289<procedure>(bind-seq-length seq)</procedure>
     290
     291returns the length of the generic sequence seq
     292(previously named seq-length)
     293
     294==== bind-seq-ref
     295
     296<procedure>(bind-seq-ref seq n)</procedure>
     297
     298returns the nth item of the generic sequence seq
     299(preveiously named seq-ref)
     300
     301==== bind-seq-tail
     302
     303<procedure>(bind-seq-tail seq n)</procedure>
     304
     305returns the tail of the generic sequence seq, starting at n
     306(previously named seq-tail)
     307
     308==== symbol-dispatcher
     309
     310<procedure>(symbol-dispatcher alist)</procedure>
     311
     312creates a documentation procedure as used in all modules
     313of this library.
     314
     315==== list-of
     316
     317<procedure>(list-of ok? ...)</procedure>
     318
     319returns a predicate which checks, if its list argument passes every
     320predicate ok? ...
     321
     322==== vector-of
     323
     324<procedure>(vector-of ok? ...)</procedure>
     325
     326returns a predicate which checks, if its vector argument passes every
     327predicate ok? ...
    441328
    442329=== Requirements
    443330
    444 None
     331procedural-macros
    445332
    446333=== Usage
     
    448335<enscript highlight=scheme>
    449336(use bindings)
    450 (import-for-syntax (only bindings bind macro-rules with-gensyms once-only))
    451337</enscript>
    452338
     
    600486; -> '(1 2))
    601487
    602 (letrec (
    603   (my-map
    604     (lambda (fn lst)
    605       (bind-case lst
    606         (() '())
    607         ((x . xs) (cons (fn x) (my-map fn xs))))))
    608   )
    609   (my-map add1 '(1 2 3)))
     488(define (my-map fn lst)
     489  (bind-case lst
     490    (() '())
     491    ((x . xs) (cons (fn x) (my-map fn xs)))))
     492(my-map add1 '(1 2 3)))
    610493; -> '(2 3 4)
     494
     495(define (vector-reverse vec)
     496  (let ((result (make-vector (vector-length vec) #f)))
     497    (let loop ((vec vec))
     498      (bind-case vec
     499        (() result)
     500        ((x . xs)
     501         (vector-set! result
     502                      (vector-length xs)
     503                      x)
     504         (loop (subvector vec 1)))))))
     505(vector-reverse #(0 1 2 3))
     506; -> #(3 2 1 0)
    611507
    612508((bind-case-lambda
     
    658554;-> '(0 1 @(2 3 4))
    659555
    660 ;; two anaphoric macros
    661 (define-syntax aif
    662   (macro-rules it ()
    663     ((_ test consequent)
    664      `(let ((,it ,test))
    665         (if ,it ,consequent)))
    666     ((_ test consequent alternative)
    667      `(let ((,it ,test))
    668         (if ,it ,consequent ,alternative)))))
    669 
    670 (define-macro (alambda args xpr . xprs)
    671   (inject self)
    672   `(letrec ((,self (lambda ,args ,xpr ,@xprs)))
    673      ,self))
    674 
    675 ;; effective membership testing
    676 (define-macro (in? what equ? . choices)
    677   (let ((insym 'in))
    678     `(let ((,insym ,what))
    679        (or ,@(map (lambda (choice) `(,equ? ,insym ,choice))
    680                   choices)))))
    681 
    682 (define-syntax vif
    683   (macro-rules (then else)
    684     ((_ test (then xpr . xprs))
    685      `(if ,test
    686         (begin ,xpr ,@xprs)))
    687     ((_ test (else xpr . xprs))
    688      `(if ,(not test)
    689         (begin ,xpr ,@xprs)))
    690     ((_ test (then xpr . xprs) (else ypr . yprs))
    691      `(if ,test
    692         (begin ,xpr ,@xprs)
    693         (begin ,ypr ,@yprs)))))
    694 
    695 ;; procedural version of cond
    696 (define-syntax my-cond
    697   (macro-rules (else =>)
    698     ((_ (else xpr . xprs))
    699      `(begin ,xpr ,@xprs))
    700     ((_ (test => xpr))
    701      (let ((temp test))
    702        `(if ,temp (,xpr ,temp))))
    703     ((_ (test => xpr) . clauses)
    704      (let ((temp test))
    705        `(if ,temp
    706           (,xpr ,temp)
    707           (my-cond ,@clauses))))
    708     ((_ (test)) `(,void))
    709     ((_ (test) . clauses)
    710      (let ((temp test))
    711        `(if ,temp
    712           ,temp
    713           (my-cond ,@clauses))))
    714     ((_ (test xpr . xprs))
    715      `(if ,test (begin ,xpr ,@xprs)))
    716     ((_ (test xpr . xprs) . clauses)
    717      `(if ,test
    718         (begin ,xpr ,@xprs)
    719         (my-cond ,@clauses)))))
    720 
    721 ;; procedural version of letrec
    722 (define-macro (my-letrec var-val-pairs . body)
    723               (where ((list-of (bindable? (var val)))
    724                       var-val-pairs))
    725   (let ((vars (map car var-val-pairs))
    726         (vals (map cadr var-val-pairs))
    727         (aux (map (lambda (x) (gensym)) var-val-pairs)))
    728     `(let ,(map (lambda (var) `(,var #f)) vars)
    729        (let ,(map (lambda (a v) `(,a ,v)) aux vals)
    730          ,@(map (lambda (v e) `(set! ,v ,e)) vars vals)
    731          ,@body))))
    732 
    733 (my-letrec ((o? (lambda (m) (if (zero? m) #f (e? (- m 1)))))
    734             (e? (lambda (n) (if (zero? n) #t (o? (- n 1))))))
    735            (list (o? 95) (e? 95)))
    736 
    737 ;; local macros
    738 (letrec-syntax (
    739      (sec (macro-rules ()
    740                ((_ lst) `(car (res ,lst)))))
    741      (res (macro-rules ()
    742              ((_ lst) `(cdr ,lst))))
    743      )
    744      (sec '(1 2 3)))
    745 ;-> 2
    746 
    747 (macro-letrec (
    748      ((sec lst) `(car (res ,lst)))
    749      ((res lst) `(cdr ,lst))
    750      )
    751      (sec '(1 2 3)))
    752 ;-> 2
    753 
    754 (macro-let (
    755      ((fir lst) (where (list? lst)) `(car ,lst))
    756      ((res lst) (where (list? lst)) `(cdr ,lst))
    757      )
    758      (fir (res '(1 2 3))))
    759 ;-> 2
    760 
    761 ;; non-symbolic literals
    762 (define-syntax foo
    763   (macro-rules ()
    764     ((_ "foo" x) x)
    765     ((_ #f x) `(list 'false))
    766     ((_ #f x) 'false)
    767     ((_ a b) (where (string? a)) `(list ,a ,b))
    768     ((_ a b) (where (odd? a)) `(list ,a ,b))
    769     ((_ a b) a)))
    770 (foo "foo" 1)
    771 ; -> 1
    772 (foo "bar" 2)
    773 ; -> '("bar" 2)
    774 (foo #f 'blabla)
    775 ; -> '(false)
    776 (foo 1 2)
    777 ; -> '(1 2)
    778 (foo 2 3)
    779 ; -> 2
    780 
    781556</enscript>
    782557
    783558== Last update
    784559
    785 Nov 15, 2015
     560Dec 04, 2015
    786561
    787562== Author
     
    821596
    822597== Version History
     598; 4.1: macro-rules and friends moved to procedural-macros, where clauses now follow patterns
    823599; 4.0: code completely rewritten,simplified  and reorganized, some small syntax changes
    824600; 3.5.2: code reorganized again to fix compile problems
Note: See TracChangeset for help on using the changeset viewer.