source: project/release/5/bindings/trunk/bindings.scm @ 38205

Last change on this file since 38205 was 38205, checked in by juergen, 7 months ago

bindings 3.1 with bind-loop to replace bind*

File size: 25.1 KB
Line 
1; Author: Juergen Lorenz, ju (at) jugilo (dot) de
2;
3; Copyright (c) 2013-2020, Juergen Lorenz
4; All rights reserved.
5;
6; Redistribution and use in source and binary forms, with or without
7; modification, are permitted provided that the following conditions are
8; met:
9;
10; Redistributions of source code must retain the above copyright
11; notice, this list of conditions and the following dispasser.
12;
13; Redistributions in binary form must reproduce the above copyright
14; notice, this list of conditions and the following dispasser in the
15; documentation and/or other materials provided with the distribution.
16;
17; Neither the name of the author nor the names of its contributors may be
18; used to endorse or promote products derived from this software without
19; specific prior written permission.
20;
21; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25; HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33#|[
34Yet another implementation of the bindings egg.
35It's based on the bind macro, which is a variant of Common Lisp's
36destructuring bind.
37
38It not only destructures nested pseudolists but nested sequences as
39well, which can be vectors, strings, biglists or what have you, provided
40you have added support for those datatypes. But that's as simple as
41adding a triple seq? seq-car and seq-cdr to the generic transformer
42procedure bind-listify*. As this name suggests, every sequence is
43transformed to an ordinary list at each nesting level. Moreover, this
44routine handles literals and dotted ends as well.
45
46The bind macro itself uses bind-list*, a nested version of bind-list,
47after having processed all literals and the wildcard, an underscore. The
48rule is, the wildcard matches everything but doesn't bind anything,
49whereas the literals match only itself, and, of course, don't bind
50anything.
51
52All other macros, in particular bind-case, a variant of match in the
53matchable egg, are based on bind and are implemented as declarative
54macros.
55
56One difference to former versions of bind is, that it can be called
57without a body which results in setting the pattern variables to
58correspondig values in the nested sequence argument. In other words,
59this is what was called bind! before. Hence bind! and
60bind-define are expendable and code duplication is avoided. But for
61convenience of use, this version is aliased bind!
62]|#
63
64(module bindings (
65  bind-listify*
66  bind-list
67  bind-list!
68  bind-list*
69  bind
70  bind!
71  bindrec
72  bind-case
73  bindable?
74  bind-lambda
75  bind-lambda*
76  bind-case-lambda
77  bind-case-lambda*
78  bind*
79  bind-loop
80  bind-let*
81  bind-let
82  bind-letrec
83  bind/cc
84  bindings
85  vector-car
86  vector-cdr
87  string-car
88  string-cdr
89  )
90
91(import scheme
92        (only (chicken condition) condition-case)
93        (only (chicken base) cut subvector gensym void receive identity print case-lambda error)
94        (only (chicken keyword) keyword?)
95        (only (chicken format) format)
96        )
97
98(import-for-syntax (only (chicken keyword) keyword?)
99                   (only (chicken format) format))
100
101(define vector-car (cut vector-ref <> 0))
102(define vector-cdr (cut subvector <> 1))
103(define string-car (cut string-ref <> 0))
104(define string-cdr (cut substring <> 1))
105
106;;; (bind-listify*)
107;;; (bind-listify* seq)
108;;; (bind-listify* pat seq)
109;;; (bind-listify* seq? seq-car seq-cdr)
110;;; ------------------------------------
111;;; the first version resets the internal database,
112;;; the second returns the car-cdr-pair corresponding to seq,
113;;; the third does the actual work transforming seq to a nested list
114;;; and the last adds support for a new sequence type.
115(define bind-listify*
116  (let ((db (list (cons (lambda (x) #t)
117                        (cons car cdr)))))
118    (case-lambda
119      (() (set! db ; reset
120            (list (cons (lambda (x) #t)
121                        (cons car cdr)))))
122      ((seq)
123       (let loop ((db db))
124         (if ((caar db) seq)
125           (cdar db)
126           (loop (cdr db)))))
127      ((pat seq)
128       (let ((gstop (gensym 'stop))
129             (seq-car (car (bind-listify* seq)))
130             (seq-cdr (cdr (bind-listify* seq)))
131             (literal? (lambda (x)
132                         (or (boolean? x)
133                             (string? x)
134                             (char? x)
135                             (number? x)
136                             (keyword? x))))
137             )
138         (let ((seq-null?
139                 (lambda (seq)
140                   (eq? (condition-case (seq-car seq)
141                          ((exn) gstop)) gstop))))
142           (let loop ((pat pat) (seq seq) (result '()))
143             (cond
144               ((null? pat)
145                (if (seq-null? seq)
146                  (reverse result)
147                  (error 'bind-listify* "length mismatch" pat seq)))
148               ;(reverse (cons seq result))))
149               ((pair? pat)
150                (let ((pfirst (car pat))
151                      (prest (cdr pat))
152                      (sfirst (seq-car seq))
153                      (srest (seq-cdr seq)))
154                  (cond
155                    ((and (symbol? pfirst) (eq? pfirst '_))
156                     (loop prest srest result))
157                    ((symbol? pfirst)
158                     (loop prest srest (cons sfirst result)))
159                    ((null? pfirst) ;;;
160                     (if (seq-null? sfirst)
161                       (loop prest
162                             srest
163                             (cons (bind-listify* pfirst sfirst) result))
164                       (error 'bind-listify* "length mismatch"
165                              pfirst sfirst)))
166                    ((pair? pfirst)
167                     (loop prest
168                           srest
169                           (cons (bind-listify* pfirst sfirst) result)))
170                    ((literal? pfirst)
171                     (if (equal? pfirst sfirst)
172                       (loop prest srest result)
173                       (error 'bind-listify*
174                              (format #f "literals ~s and ~s not equal?~%"
175                                      pfirst sfirst))))
176                    (else (error 'bind-listify*
177                                 (format #f "~s is not a valid literal~%")
178                                 pfirst))
179                    )))
180               (else
181                 (cond
182                   ((and (symbol? pat) (eq? pat '_))
183                    (reverse result))
184                   ((symbol? pat)
185                    (reverse (cons seq result)))
186                   ((literal? pat)
187                    (if (equal? pat seq)
188                      (reverse result)
189                      (error 'bind-listify*
190                              (format #f "literals ~s and ~s not equal?~%"
191                                      pat seq))))
192                   (else (error 'bind-listify*
193                                (format #f "~s is not a valid literal~%")
194                                pat))
195                   )))))))
196      ((seq? seq-car seq-cdr)
197       (set! db (cons (cons seq?
198                            (cons seq-car seq-cdr)) db)))
199      )))
200       
201
202;;; (bind-list pat lst . body)
203;;; --------------------------
204;;; flat versions of bind (symbol-lists only)
205(define-syntax bind-list
206  (ir-macro-transformer
207    (lambda (form inject compare?)
208      (let ((pat (cadr form)))
209        (if (null? (cddr form))
210          `(begin ,@(map (lambda (var)
211                           `(set! ,var ',var))
212                         pat))
213          (let ((lst (caddr form))); (seq (gensym)))
214            (if (null? (cdddr form))
215              ;`(begin ,@(map (lambda (var val)
216              ;                 `(set! ,var ,val))
217              ;               pat (eval lst)))
218              `(if (= ,(length pat) (length ,lst))
219                (begin
220                   ,@(let loop ((pat pat) (lst lst))
221                       (if (null? pat)
222                         '()
223                         (cons `(set! ,(car pat) (car ,lst))
224                               (loop (cdr pat) `(cdr ,lst))))))
225                (error 'bind-list "length mismatch" ',pat ,lst))
226              `(apply (lambda ,pat ,@(cdddr form))
227                      ,lst))))))))
228;(define-syntax bind-list
229;  (syntax-rules ()
230;    ((_ () ls)
231;     (if (null? ls)
232;       (if #f #f)
233;       (error 'bind-list "length mismatch" '() ls)))
234;    ((_ (a . as) ls)
235;     (begin (set! a (car ls)) (bind-list as (cdr ls))))
236;    ((_ pat)
237;     (bind-list pat 'pat))
238;    ((_ xs ls . body)
239;     (apply (lambda xs . body) ls))
240;    ))
241
242;;; (bind-list! pat lst)
243;;; (bind-list! pat)
244;;; --------------------
245;;; list version of bind!
246(define-syntax bind-list!
247  (syntax-rules ()
248    ((_ pat lst)
249     (bind-list pat lst))
250    ((_ pat)
251     (bind-list pat 'pat))
252    ))
253
254;;; (bind-list* pat seq . body)
255;;; ---------------------------
256;;; nested versions of bind (symbol-lists only)
257(define-syntax bind-list*
258  (er-macro-transformer
259    (lambda (form rename compare?)
260      (let ((pat (cadr form))
261            (seq (caddr form))
262            (body (cdddr form))
263            (%_ (rename '_))
264            (%let (rename 'let))
265            (%set! (rename 'set!))
266            (%bind (rename 'bind))
267            (%apply (rename 'apply))
268            (%begin (rename 'begin))
269            (%lambda (rename 'lambda))
270            (%bind-list (rename 'bind-list))
271            (%bind-list* (rename 'bind-list*))
272            )
273          (let* ((pat* (map (lambda (s)
274                          (if (symbol? s)
275                            s
276                            (cons (gensym) s)))
277                        pat))
278                 (flat-pat* (map (lambda (s)
279                                   (if (symbol? s)
280                                     s
281                                     (car s)))
282                                 pat*)))
283            (receive (pairs syms)
284              (let loop ((lst pat*) (yes '()) (no '()))
285                (cond
286                  ((null? lst)
287                   (values (reverse yes) (reverse no)))
288                  ((pair? (car lst))
289                   (loop (cdr lst) (cons (car lst) yes) no))
290                  ((symbol? (car lst))
291                   (loop (cdr lst) yes (cons (car lst) no)))
292                  (else (error 'bind "can't happen"))))
293              (if (null? body)
294                ;; without body
295                (if (null? pairs) ; flat list
296                  `(,%bind-list ,syms ,seq)
297                  ;; (bind-list* (a (b c)) '(1 (2 3)))
298                  ;; ->
299                  ;; (begin (bind-list (a g) seq)
300                  ;;        (bind-list* (b c) g))
301                  `(,%begin (,%bind-list ,flat-pat* ,seq)
302                            ,@(map (lambda (pair)
303                                     `(,%bind ,(cdr pair) ,(car pair)))
304                                   pairs)))
305                ;; with body
306                (let ((xpr (car body)) (xprs (cdr body)))
307                  (if (null? pairs) ; flat list
308                    ;`(,%apply (,%lambda ,syms ,xpr ,@xprs) ,seq)
309                    `(,%bind-list ,syms ,seq ,xpr ,@xprs)
310                    ;; (bind-list* (a (b c)) '(1 (2 3)) body)
311                    ;; ->
312                    ;; (apply (lambda (a g) (bind-list* (b c) g body))
313                    ;; seq)
314                    `(,%apply
315                       (,%lambda ,flat-pat*
316                                 ,(let loop ((pairs pairs))
317                                     (if (null? pairs)
318                                       `(,%begin ,xpr ,@xprs)
319                                       `(,%bind-list* ,(cdar pairs)
320                                                      ,(caar pairs)
321                                                      ,(loop (cdr pairs))))))
322                       ,seq)
323                     )))))))))
324
325;;; (bind pat seq . body)
326;;; ---------------------
327(define-syntax bind
328  (er-macro-transformer
329    (lambda (form rename compare?)
330      (let (
331        (pat (cadr form))
332        (seq (caddr form))
333        (body (cdddr form))
334        (%_ (rename '_))
335        (%bind-list* (rename 'bind-list*))
336        (%bind-listify* (rename 'bind-listify*))
337        (literal? (lambda (x)
338                    (or (boolean? x)
339                        (string? x)
340                        (char? x)
341                        (number? x)
342                        (keyword? x))))
343        )
344        (letrec (
345          (listify*
346            (lambda (pat)
347              (let loop ((pat pat) (result '()))
348                (cond
349                  ((null? pat)
350                   (reverse result))
351                  ((and (symbol? pat) (compare? pat %_))
352                   (reverse result))
353                  ((symbol? pat)
354                   (reverse (cons pat result)))
355                  ((literal? pat)
356                   (reverse result))
357                  ((pair? pat)
358                   (let ((first (car pat))
359                         (rest (cdr pat)))
360                     (cond
361                       ((and (symbol? first)
362                             (compare? first %_))
363                        (loop rest result))
364                       ((symbol? first)
365                        (loop rest (cons first result)))
366                       ((null? first) ;;;
367                        (loop rest (cons first result)))
368                       ((pair? first)
369                        (loop rest (cons (listify* first) result)))
370                       ((literal? first)
371                        (loop rest result))
372                       )))))))
373          )
374          (if (null? body)
375            ;; without body
376            `(,%bind-list* ,(listify* pat)
377                           (,%bind-listify* ',pat ,seq))
378            ;; with body
379            (let ((xpr (car body)) (xprs (cdr body)))
380              `(,%bind-list* ,(listify* pat)
381                             (,%bind-listify* ',pat ,seq)
382                             ,xpr ,@xprs)))
383          )))))
384
385;;; (bind! pat seq)
386;;; (bind! pat)
387;;; ---------------
388;;; alias to bind without body
389(define-syntax bind!
390  (syntax-rules ()
391    ((_ pat seq)
392     (bind pat seq))
393    ((_ pat)
394     (bind pat 'pat))))
395
396#|[
397The following macro does more or less the same what the match macro from
398the matchable package does, for example
399
400  (bind-case '(1 (2 3))
401    ((x y) (>> y list?) (list x y))
402    ((x (y . z)) (list x y z))
403    ((x (y z)) (list x y z))) ;-> '(1 2 (3))
404
405or, to give a more realistic example, mapping:
406
407  (define (my-map fn lst)
408    (bind-case lst
409      (() '())
410      ((x . xs) (cons (fn x) (my-map fn xs)))))
411]|#
412
413;;; (bind-case seq (pat xpr ....) ....)
414;;; -----------------------------------
415;;; Checks if seq matches patterns pat  ....
416;;; in sequence, binds the pattern variables of the first matching
417;;; pattern to corresponding subexpressions of seq and executes
418;;; body expressions xpr .... in this context
419(define-syntax bind-case
420  (syntax-rules ()
421    ((_ seq)
422     (error 'bind-case "no match for" seq))
423    ((_ seq (pat xpr . xprs))
424     (condition-case (bind pat seq xpr . xprs)
425       ((exn) (bind-case seq))))
426    ((_ seq clause . clauses)
427     (condition-case (bind-case seq clause)
428       ((exn) (bind-case seq . clauses))))
429    ))
430
431;;; (bindable? pat)
432;;; ---------------
433;;; returns a unary predicate which checks, if its arguments match pat
434(define-syntax bindable?
435  (syntax-rules ()
436    ((_ pat)
437     (lambda (seq)
438        (condition-case (bind pat seq #t)
439          ((exn) #f))))
440    ))
441
442#|[
443Now we can define two macros, which simply combine lambda with
444bind, the first destructures simply one argument, the second a
445whole list. An example of a call and its result is
446
447  ((bind-lambda (a (b . c) . d) (list a b c d))
448   '(1 #(20 30 40) 2 3))
449  -> '(1 20 #(30 40) (2 3)))))
450
451  ((bind-lambda* ((a (b . c) . d) (e . f))
452     (list a b c d e f))
453   '(1 #(20 30 40) 2 3) '#(4 5 6))
454  -> '(1 20 #(30 40) (2 3) 4 #(5 6)))
455]|#
456
457;;; (bind-lambda pat xpr ....)
458;;; --------------------------
459;;; combination of lambda and bind, one pattern argument
460(define-syntax bind-lambda
461  (syntax-rules ()
462    ((_ pat xpr . xprs)
463     (lambda (x) (bind pat x xpr . xprs)))
464    ))
465
466;;; (bind-lambda* pat xpr ....)
467;;; ---------------------------
468;;; combination of lambda and bind, multiple pattern arguments
469(define-syntax bind-lambda*
470  (syntax-rules ()
471    ((_ pat xpr . xprs)
472     (lambda x (bind pat x xpr . xprs)))
473     ))
474
475#|[
476The next two macros combine lambda and bind-case and do more or less the
477same as match-lambda and match-lambda* in the matchable package. The
478first destructures one argument, the second a list of arguments.
479Here is an example together with its result (note the >> fender):
480
481  ((bind-case-lambda
482     ((a (b . c) . d) (list a b c d))
483     ((e . f) (>> e zero?) e)
484     ((e . f) (list e f)))
485   '(1 2 3 4 5))
486  -> '(1 (2 3 4 5))
487
488  ((bind-case-lambda*
489     (((a (b . c) . d) (e . f))
490      (list a b c d e f)))
491   '(1 #(20 30 40) 2 3) '(4 5 6))
492  -> '(1 20 (30 40) (2 3) 4 (5 6))
493]|#
494
495;;; (bind-case-lambda (pat xpr ....) ....)
496;;; --------------------------------------
497;;; combination of lambda and bind-case, one pattern argument
498(define-syntax bind-case-lambda
499  (syntax-rules ()
500    ((_ (pat xpr . xprs))
501     (lambda (x)
502       (bind-case x (pat xpr . xprs))))
503    ((_ clause . clauses)
504     (lambda (x)
505       (bind-case x clause . clauses)))
506    ))
507
508;;; (bind-case-lambda* (pat xpr ....) ....)
509;;; ---------------------------------------
510;;; combination of lambda and bind-case, multiple pattern arguments
511(define-syntax bind-case-lambda*
512  (syntax-rules ()
513    ((_ (pat xpr . xprs))
514     (lambda x
515       (bind-case x (pat xpr . xprs))))
516    ((_ clause . clauses)
517     (lambda x
518       (bind-case x clause . clauses)))
519    ))
520
521#|[
522The following macro, bind-loop, is an anaphoric version of bind.
523It introduces an unrenamed symbol, loop, behind the scene and binds it
524to a procedure, which can be used in the body.
525For example
526
527  (bind-loop (x y) '(5 0)
528    (if (zero? x)
529      (list x y)
530      (loop (list (sub1 x) (add1 y)))))
531  -> '(0 5)
532]|#
533
534;;; (bind-loop pat seq xpr ....)
535;;; ---- ------------------------
536;;; anaphoric version of bind, introducing loop routine behind the scene
537(define-syntax bind-loop
538  (er-macro-transformer
539    (lambda (form rename compare?)
540      (let ((pat (cadr form))
541            (seq (caddr form))
542            (xpr (cadddr form))
543            (xprs (cddddr form))
544            (%letrec (rename 'letrec))
545            (%bind-lambda (rename 'bind-lambda)))
546        `((,%letrec ((loop (,%bind-lambda ,pat ,xpr ,@xprs)))
547            loop)
548          ,seq)))))
549
550#|[
551The following macro, bind*, is a named version of bind. It takes an
552additional argument besides those of bind, which is bound to a
553recursive procedure, which can be called in bind's body. The pattern
554variables are initialised with the corresponding subexpressions in seq.
555For example
556
557  (bind* loop (x y) '(5 0)
558    (if (zero? x)
559      (list x y)
560      (loop (list (sub1 x) (add1 y)))))
561  -> '(0 5)
562]|#
563
564;;; (bind* name pat seq xpr ....)
565;;; ---- ------------------------
566;;; named version of bind
567(define-syntax bind*
568  (syntax-rules ()
569    ((_ name pat seq xpr . xprs)
570     ((letrec ((name (bind-lambda pat xpr . xprs)))
571        name)
572      seq))))
573
574#|[
575The following three macros are analoga of the standard base macros let,
576let* and letrec, the first named or unnamed. For example
577
578(bind-let loop (((a b) '(5 0)))
579  (if (zero? a)
580    (list a b)
581    (loop (list (sub1 a) (add1 b)))))
582-> '(0 5)
583
584A recursive version of bind follows
585]|#
586
587;;; (bind-let* ((pat seq) ...) xpr . xprs)
588;;; --------------------------------------
589;;; sequentually binding patterns to sequences
590(define-syntax bind-let*
591  (syntax-rules ()
592    ((_ () xpr . xprs)
593     (let () xpr . xprs))
594    ((_ ((pat seq)) xpr . xprs)
595     (bind pat seq xpr . xprs))
596    ((_ ((pat seq) (pat1 seq1) ...) xpr . xprs)
597     (bind pat seq (bind-let* ((pat1 seq1) ...) xpr . xprs)))
598     ))
599
600;;; (bind-let name .. ((pat seq) ...) xpr . xprs)
601;;; ---------------------------------------------
602;;; binding patterns to sequences in parallel, whith or without a
603;;; recursive name procedure
604(define-syntax bind-let
605  (syntax-rules ()
606    ((_ ((pat seq) ...) xpr . xprs)
607     (bind (pat ...) (list seq ...) xpr . xprs))
608    ((_ name ((pat seq) ...) xpr . xprs)
609     ((letrec ((name (bind-lambda* (pat ...) xpr . xprs)))
610        name)
611      seq ...))
612    ))
613
614;;; (bind-letrec ((pat seq) ...) xpr . xprs)
615;;; ----------------------------------------
616;;; binding patterns to sequences recursively
617(define-syntax bind-letrec
618  (syntax-rules ()
619    ((_ ((pat seq) ...) xpr . xprs)
620     (bind-let ((pat 'pat) ...)
621       (bind! (pat ...) (list seq ...))
622       xpr . xprs))))
623   
624;;; (bindrec pat seq xpr . xprs)
625;;; ----------------------------
626;;; recursive version of bind
627(define-syntax bindrec
628  (syntax-rules ()
629    ((_ pat seq xpr . xprs)
630     (bind pat 'pat
631       (bind! pat seq)
632       xpr . xprs))))
633
634#|[
635I don't like the let/cc syntax, because it differs from let syntax,
636here is bind/cc, which does the same.
637]|#
638
639;;; (bind/cc cc xpr ....)
640;;; ---------------------
641;;; captures the current continuation, binds it to cc and executes
642;;; xpr .... in this context
643(define-syntax bind/cc
644  (syntax-rules ()
645    ((_ cc xpr . xprs)
646     (call-with-current-continuation
647       (lambda (cc) xpr . xprs)))))
648
649(define (symbol-dispatcher alist) ; internal
650  (case-lambda
651    (()
652     (map car alist))
653    ((sym)
654     (let ((pair (assq sym alist)))
655       (if pair
656         (for-each print (cdr pair))
657         (error "Not in list"
658                sym
659                (map car alist)))))))
660
661;;; (bindings sym ..)
662;;; -----------------
663;;; documentation procedure
664(define bindings
665  (symbol-dispatcher '(
666    (bindings
667      procedure:
668      (bindings sym ..)
669      "documentation procedure")
670    (bind-listify*
671      generic procedure:
672      (bind-listify*)
673      "resets the internal database for lists only"
674      (bind-listify* seq)
675      "returns the car-cdr-pair corresponding to seq"
676      (bind-listify* pat seq)
677      "transforms the nested pseudolist seq to a nested list"
678      (bind-listify* seq? seq-car seq-cdr)
679      "adds support for a new sequence type to the"
680      "internal database")
681    (bind-list
682      macro:
683      (bind-list pat lst . body)
684      "flat version of bind: destructure symbol-lists only")
685    (bind-list!
686      macro:
687      (bind-list! pat lst)
688      "alias to bind-list wtihout body"
689      (bind-list! pat)
690      "alias to (bind-list! pat 'pat)")
691    (bind-list*
692      macro:
693      (bind-list* pat seq . body)
694      "nested version of bind: destructure symbol-lists only"
695      "multiple set!s without")
696    (bind
697      macro:
698      (bind pat seq . body)
699      "a variant of Common Lisp's destructuring-bind with body"
700      "multiple set!s without")
701    (bind-case
702      macro:
703      (bind-case seq (pat xpr ....) ....)
704      "matches seq against pat with optional fenders in a case regime")
705    (bindable?
706      macro:
707      (bindable? pat)
708      "returns a unary predicate, which checks"
709      "if its argument matches pat and passes all fenders")
710    (bind!
711      macro:
712      (bind! pat seq)
713      "sets multiple variables by destructuring its sequence arguments")
714    (bind-lambda
715      macro:
716      (bind-lambda pat xpr ....)
717      "combination of lambda and bind, one pattern argument")
718    (bind-lambda*
719      macro:
720      (bind-lambda* pat xpr ....)
721      "combination of lambda and bind, multiple pattern arguments")
722    (bind*
723      macro:
724      (bind* loop pat seq xpr ....)
725      "named version of bind,"
726      "deprecated, use bind-loop instead")
727    (bind-loop
728      macro:
729      (bind-loop pat seq xpr ....)
730      "anaphoric version of bind,"
731      "introduces a routine named loop behind the scene,"
732      "to be used in the body xpr ....")
733    (bind-let
734      macro:
735      (bind-let loop .. ((pat seq) ...) xpr ....)
736      "nested version of let, named and unnamed")
737    (bind-let*
738      macro:
739      (bind-let* ((pat seq) ...) xpr ....)
740      "nested version of let*")
741    (bindrec
742      macro:
743      (bindrec pat seq xpr ....)
744      "recursive version of bind")
745    (bind-letrec
746      macro:
747      (bind-letrec ((pat seq) ...) xpr ....)
748      "recursive version of bind-let")
749    (bind-case-lambda
750      macro:
751      (bind-case-lambda (pat xpr ....) ....)
752      "combination of lambda and bind-case with one pattern argument")
753    (bind-case-lambda*
754      macro:
755      (bind-case-lambda* (pat xpr ....) ....)
756      "combination of lambda and bind-case with multiple pattern arguments")
757    (bind/cc
758      macro:
759      (bind/cc cc xpr ....)
760      "binds cc to the current contiunation"
761      "and execute xpr ... in this context")
762    (vector-car
763      procedure:
764      (vector-car vec)
765      "vector-analog of car")
766    (vector-cdr
767      procedure:
768      (vector-cdr vec)
769      "vector-analog of cdr")
770    (string-car
771      procedure:
772      (string-car vec)
773      "string-analog of car")
774    (string-cdr
775      procedure:
776      (string-cdr vec)
777      "string-analog of cdr")
778    )))
779
780) ; module
781
Note: See TracBrowser for help on using the repository browser.