Changeset 39397 in project


Ignore:
Timestamp:
11/27/20 17:47:10 (5 months ago)
Author:
juergen
Message:

bindings 5.0 docu

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/5/bindings

    r38813 r39397  
    1616pattern and can be easily enhanced to accept other sequence types as
    1717well, vectors, strings, arrays, or what have you. All this sequence
    18 types can be nested and mixed as you need it. This flexibility is made
    19 possible by one generic function, bind-listify*, which can add three
    20 (or four) procedures, seq?, seq-car, seq-cdr (and possibly seq-null?)
    21 to its local database and thus supplying support for a new sequence type.
    22 
    23 The fundamental bind macro is given in two forms, whith and without a
    24 body. The former is a variant of Common Lisp's destructuring-bind, the
    25 latter simply set!s pattern variables to the corresponding sequence
    26 values.
     18types can be nested and mixed as you need it.
     19
     20This version uses the sequence routines from simple-sequences and is
     21based again on Paul Graham's dbind (On Lisp, p. 232), a version of
     22Common Lisp's destructuring-bind.
     23
     24But this version of dbind supports setters as well, using dbind without
     25body. The reason to put it all in one huge macro is, that both variants
     26use a common set of subroutines, which are implemented within the macro
     27body. I could have put it into a helper module to be imported by syntax,
     28but this subroutines are without interest outside of dbind.
     29
     30Other enhancements include length checks of sequences, a wildcard, _, which
     31matches everything and binds nothing, literals, which match only
     32themselfs but can't of course be bound, and dots, which are extensions of
     33ellipses: two dots accept zero or one items of the same shape as the
     34nested list to its left, and four dots accept only non-empty nested
     35lists.
     36
     37Note, that dbind is not exported, bind and bind! are exported instead.
    2738
    2839<macro>(bind pat seq xpr . xprs)</macro>
    29 <macro>(bind pat seq)</macro>
     40<macro>(bind! pat seq)</macro>
    3041
    3142Here, a pattern, pat, is either
     
    3647* a pair of patterns.
    3748
    38 where dotted lists (i.e list patterns followed by two, tree or four dots)
    39 are new in version 4.0.
    40 
    41 seq is a nested sequence expression, i.e. a mixture of pseudolists,
    42 vectors and strings (after having added string and vector support to a
    43 generic transformer procedure, bind-listify*). This transformer procedure
    44 is used to transform seq into a nested list.
     49where dotted lists (i.e nested list patterns followed by two, tree or
     50four dots) are new since version 4.0, and seq is a nested sequence
     51expression, i.e. a mixture of pseudolists, vectors and strings. Other
     52sequence types can be added by means of sequence-db, which is reexported
     53from simple-sequences.
    4554
    4655Patterns are used to control the destructuring of sequences, bind
    47 pattern variables (i.e. symbols in pat except the wildcard, _, which
    48 matches everything, but binds nothing) to matching subexpressions of seq
    49 and check if literals in pat are equal to matching subexpressions in seq.
     56pattern variables to corresponding subexpressions of seq, controlling
     57their length and checking if literals match themselfs. Then either the
     58body is executed in this context, or the pattern variables are set! to
     59the values of the corresponding subexpression.
    5060Since the wildcard binds nothing, it can appear multiple times in the
    5161same macro.
    5262
    53 Dots might not only follow patterns but also expressions.
    54 Their meaning is
    55 
    56 * two dots: the expression to the left appears zero or one times,
    57 * three dots: zero or many times,
    58 * four dots: one or many times.
    59 
    6063=== Documentation
     64
     65==== sequence-db
     66 
     67<procedure>(sequence-db)</procedure>
     68<procedure>(sequence-db seq)</procedure>
     69<procedure>(sequence-db seq? seq-length seq-ref seq-tail seq-maker . pos?)</procedure>
     70
     71database processing:
     72the first resets the database to the standard with
     73lists, pairs, vectors and strings,
     74the second returns the vector of handlers as well as the discriminator,
     75the third adds a new database record either at the end or before the
     76pos? discriminator.
     77A record cosists of a discriminator, seq?, and a vector with items
     78seq-lenth, seq-ref, seq-tail and seq-maker patterned after vectors.
     79Note, that the last record can handle atoms, albeit it is not a
     80sequence.
     81This routine is reexported from simple-sequences.
    6182
    6283==== bindings
     
    6788such an exported symbol, respectively.
    6889
    69 === Procedures
    70 
    71 ==== bind-listify*
    72 
    73 This is a generic procedure. It is closed over a local database which
    74 contains the necessary sequence versions of car and cdr and possibly
    75 null?
    76 
    77 <procedure>(bind-listify*)</procedure>
    78 
    79 resets the internal database for lists only.
    80 
    81 <procedure>(bind-listify* seq)</procedure>
    82 
    83 returns the car-cdr-(respectivley car-cdr-null?)-list corresponding
    84 to seq's type.
    85 
    86 <procedure>(bind-listify* pat seq)</procedure>
    87 
    88 transforms a nested pseudolist with possible wildcard, literals
    89 and dotted lists to a an ordinary nested list without.
    90 
    91 <procedure>(bind-listify* seq? seq-car seq-cdr)</procedure>
    92 
    93 adds support for a new sequence type with predicate seq? and
    94 sequence variants of car and cdr to the internal database.
    95 
    96 <procedure>(bind-listify* seq? seq-car seq-cdr seq-null?)</procedure>
    97 
    98 the same as before but with a null?-variant of seq (if not given, it is
    99 constructed in bind's body).
    100 
    101 ==== vector-car
    102 
    103 <procedure>(vector-car vec)</procedure>
    104 
    105 vector-variant of car.
    106 
    107 ==== vector-cdr
    108 
    109 <procedure>(vector-cdr vec)</procedure>
    110 
    111 vector-variant of cdr.
    112 
    113 ==== vector-null?
    114 
    115 <procedure>(vector-null? vec)</procedure>
    116 
    117 vector-variant of null?.
    118 
    119 ==== string-car
    120 
    121 <procedure>(string-car vec)</procedure>
    122 
    123 string-variant of car.
    124 
    125 ==== string-cdr
    126 
    127 <procedure>(string-cdr vec)</procedure>
    128 
    129 string-variant of cdr.
    130 
    131 ==== string-null?
    132 
    133 <procedure>(string-null? vec)</procedure>
    134 
    135 string-variant of null?.
    136 
    137 === Binding macros
    138 
    139 ==== bind-list
    140 
    141 <macro>(bind-list pat lst . body)</macro>
    142 
    143 with body:
    144 binds pattern variables of of a nested list patern without wildcard, literals
    145 and dotted ends, pat,
    146 to corresponding values of a nested list
    147 and executes the body in this context.
    148 
    149 withoud body:
    150 set!s pattern variables of a nested list patern without wildcard, literals
    151 and dotted ends, pat, to corresponding values of a nested list.
    152 
    153 ==== bind-list!
    154 
    155 <macro>(bind-list! pat lst)</macro>
    156 <macro>(bind-list! pat)</macro>
    157 
    158 the former is an alias to bind-list without body,
    159 the latter is (bind-list! pat 'pat)
    160 
    16190==== bind
    16291
    163 <macro>(bind pat seq . body)</macro>
    164 
    165 with body:
     92<macro>(bind pat seq xpr . xprs)</macro>
     93
    16694binds pattern variables of a nested patern, pat, possibly with wildcard,
    167 literals and dotted ends
    168 to corresponding values of a nested sequence, seq, possibly with
    169 literals and dotted ends, and executes the body xpr .... in this context.
    170 
    171 without body:
    172 set!s pattern variables of a nested patern, pat, possibly with wildcard,
    173 literals and dotted ends,
    174 to corresponding values of a nested sequences, seq, possibly with literals
    175 and dotted ends.
     95literals and dotted ends to corresponding values of a nested sequence,
     96seq, and executes the body xpr .... in this context.
    17697
    17798==== bind!
     
    180101<macro>(bind! pat)</macro>
    181102
    182 the former is an alias to bind without body,
    183 the latter (bind! pat 'pat).
     103set!s pattern variables of a nested pattern, pat, possibly with
     104wildcard, literals and dotted ends, to corresponding values of a nested
     105sequences, seq. If no seq is given, 'pat is used.
    184106
    185107==== bind*
     
    276198context.
    277199
    278 ==== resolve-dots
    279 
    280 <macro>(resolve-dots . args)</macro>
    281 
    282 transforms the list args, which might contain lists followed by dots
    283 into a list without dots and the list to dots' left spliced into the
    284 result.
    285 
    286200=== Requirements
    287201
    288 None
     202simple-sequences
    289203
    290204=== Examples
     
    292206<enscript highlight=scheme>
    293207
    294 (import bindings checks)
    295 
    296 ;; reset local database to nested pseudolists only
    297 (bind-listify*)
    298 
    299 ;; add vector and string support
    300 (bind-listify* vector? vector-car vector-cdr)
    301 (bind-listify* string? string-car string-cdr)
    302 
    303 (bind-listify* 'a 1) ; -> '(1)
    304 (bind-listify* '(a . as) #(1 2 3))
    305 ;-> '(1 #(2 3)))
    306 (bind-listify* '(a (b #f) c) '(1 #(2 #f) 3))
    307 ;-> '(1 (2) 3))
    308 (bind-listify* '(a (b (c _ . cs) d) . es) #(1 (2 (3 30 300) 4) 50))
    309 ;-> '(1 (2 (3 (300)) 4) #(50)))
    310 (bind-listify* '(a (_ b _) . c) '(1 #(20 30 40) 5))
    311 ;-> '(1 (30) (5)))
    312 (bind-listify* '(x y as ... b c) '(-2 -1 1 2 3 40 50))
    313 ;-> '(-2 -1 (1 2 3) 40 50)
    314 (bind-listify* '(x y as .. b c) '(-2 -1 40 50))
    315 ;-> '(-2 -1 () 40 50)
    316 (bind-listify* '((as (bs cs)) ... d e) '((1 (2 3)) (10 (20 30)) 4 5))
    317 ;-> '(((1 10) ((2 20) (3 30))) 4 5)
    318 
    319 (bind-list (x (y (z))) '(1 (2 (3))) (list x y z))
    320 ; -> '(1 2 3)
    321 
    322 (let ()
    323   (bind-list! (u v w))
    324   (and (eq? u 'u) (eq? v 'v) (eq? w 'w)))
    325 : -> #t
     208(import simple-sequences bindings checks)
    326209
    327210(let ((stack #f) (push! #f) (pop! #f))
     
    353236; -> 1
    354237
    355 (bind (x y as .... d e) '(-1 0 1 2 3 4 5) (list x y as d e))
    356 ;-> '(-1 0 (1 2 3) 4 5)
    357 
    358 (bind (x y as .. d e) '(-1 0 4 5)  (list x y as d e))
    359 ;-> '(-1 0 () 4 5)
    360 
    361 (bind ((as (bs cs)) ... d e)
    362       '((1 (2 3)) (10 (20 30)) 4 5)
    363       (list as bs cs d e))
    364 ;-> '((1 10) (2 20) (3 30) 4 5)
     238(bind (x y as ....) '(-1 0 1 2 3 4) (list x y as))
     239;-> '(-1 0 (1 2 3))
     240
     241(bind (x y as ..) '(-1 0)  (list x y as))
     242;-> '(-1 0 ())
     243
     244(bind ((as (bs cs)) ...)
     245      '((1 (2 3)) (10 (20 30)))
     246      (list as bs cs))
     247;-> '((1 10) (2 20) (3 30))
    365248
    366249(bind (x y z w) '(1 2 3 4) (list x y z w))
     
    516399
    517400(bind-case '(0 4)
    518   ((a bs .... c) #f)
    519   ((a bs ... c) (list a bs c)))
    520 ;-> '(0 () 4)
     401  ((a bs ....) #f)
     402  ((a bs ...) (list a bs)))
     403;-> '(0 ())
    521404
    522405(bind-case '(0 1 2 3 4)
    523   ((a bs .. c) #f)
    524   ((a bs ... c) (list a bs c)))
    525 ;-> '(0 (1 2 3) 4)
     406  ((a bs ..) #f)
     407  ((a bs ...) (list a bs)))
     408;-> '(0 (1 2 3))
    526409
    527410(bind-case '(0 #(1 (2 3)) 4)
    528   ((a (bs (cs (ds))) .. e) #f)
    529   ((a (bs (cs ds)) .. e) (list a bs cs ds e)))
    530 ;-> '(0 (1) (2) (3) 4)
     411  ((a (bs (cs (ds))) ..) #f)
     412  ((a (bs (cs ds)) ..) (list a bs cs ds)))
     413;-> '(0 (1) (2) (3))
    531414
    532415(define (my-map fn lst)
     
    581464; -> '(1 20 #(30 40) (2 3) 4 (5 6))
    582465
    583 (resolve-dots 1 '(20 30) ... 4 '(40 50 60) .... 7)
    584 ; -> '(1 20 30 4 40 50 60 7)
    585466</enscript>
    586467
    587468== Last update
    588469
    589 Aug 01, 2020
     470Nov 27, 2020
    590471
    591472== Author
     
    625506
    626507== Version History
     508; 5.0 ; new version based again on Graham's dbind, using simple-sequences
    627509; 4.1 ; dotted lists in bodies added via resolve-dots
    628510; 4.0 ; dotted patterns added
Note: See TracChangeset for help on using the changeset viewer.