Changeset 33169 in project


Ignore:
Timestamp:
02/07/16 06:05:24 (3 years ago)
Author:
jacius
Message:

ck-macros: Final docs for version 0.1.0.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/ck-macros

    r33159 r33169  
    33Composable Scheme macros based on the CK abstract machine.
    44
    5 The ck-macros egg provides Oleg Kiselyov's CK-macro system, describe in the article,
    6 [[http://okmij.org/ftp/Scheme/macros.html#ck-macros|Applicative syntax-rules: macros that compose better]].
    7 
    8 This egg provides version 1.1 (April 2011) of the core {{ck}} macro,
    9 which is the latest version as of this writing.
    10 This egg also provides many useful (and some not-so-useful) predefined CK-macros.
     5This egg is based on the CK-macro system described in
     6"[[http://okmij.org/ftp/Scheme/macros.html#ck-macros|Applicative syntax-rules: macros that compose better]]"
     7by Oleg Kiselyov.
     8This egg provides the core {{ck}} macro,
     9plus many useful (and some not-so-useful) predefined CK-macros.
    1110
    1211If you create a useful or interesting general-purpose CK-macro,
    1312or an improvement to an existing CK-macro,
    14 please contact the maintainer so your contribution can be added to the library.
     13please contact the maintainer (John) so your contribution can be added to the egg.
    1514All source code (including contributions) is public domain.
    1615
    17 ; Project / Source Code Repository : [[https://gitlab.com/jcroisant/ck-macros]]
    18 ; Author : Oleg Kiselyov, with additional CK-macros and documentation by [[users/john-croisant|John Croisant]]
    19 ; Egg Maintainer : [[users/john-croisant|John Croisant]]
     16; Project / Source Code Repository: [[https://gitlab.com/jcroisant/ck-macros]]
     17; Maintainer: [[/users/john-croisant|John Croisant]]
     18; Based on work by: Oleg Kiselyov
    2019; License: Public Domain
    2120
    2221
    23 '''Table of Contents:'''
     22'''Table of Contents'''
    2423[[toc:]]
    2524
    2625
     26=== Version History
     27
     28; 0.1.0 (2016-02-06) : Initial release. Includes version 1.1 (April 2011) of the core {{ck}} macro. Includes many CK-macros.
     29
     30For more information about what changed in each version,
     31see the [[https://gitlab.com/jcroisant/ck-macros/blob/master/CHANGELOG.md|CHANGELOG]].
     32
     33
    2734=== What are CK-macros?
    2835
     
    3037
    3138The core {{ck}} macro is a {{syntax-rules}} macro which implements the CK abstract machine.
    32 The CK abstract machine is a computational model described by Matthias Felleisen and Daniel P. Friedman
    33 in the paper, "Control Operators, the SECD-Machine, and the Lambda-Calculus".
    34 Fortunately, you don't need to understand the paper in order to create or use CK-macros!
    35 
    36 Basically, the core {{ck}} macro does some clever rearranging to expand the CK-macro's arguments,
     39The CK abstract machine is a theoretical model of computation,
     40described in the paper "Control Operators, the SECD-Machine, and the Lambda-Calculus"
     41by Matthias Felleisen and Daniel P. Friedman.
     42But, you don't need to read or understand the paper in order to create or use CK-macros!
     43
     44Basically, a CK-macro leverages the core {{ck}} macro
     45to recursively expand the CK-macros's arguments first,
     46before the CK-macro itself is expanded.
     47This gives you more control over the macro expansion process,
    3748allowing you to easily combine simple reusable macros to form more complex macros.
    38 This is very similar to the way Scheme makes it easy to combine simple resuable functions
     49
     50This is very similar to the way Scheme allows you to easily combine simple resuable functions
    3951({{map}}, {{fold}}, {{cons}}, etc.) to create more complex functions.
    4052In fact, many useful Scheme functions can be translated to CK-macros,
    41 allowing you to achieve the same effect at macro-expansion time!
    42 
    43 CK-macros give you a lot of control over the macro expansion process,
    44 which allows you to implement many kinds of macros much more simply
    45 than you could with traditional style {{syntax-rules}} macros.
     53allowing you to portably achieve the same effect at macro-expansion time.
    4654You can even implement "higher-ordered macros" which take a macro as an argument.
    4755See {{c-map}} and {{c-fold}} for examples of higher-ordered macros.
     
    5058CHICKEN's [[/manual/Macros|explicit and implicit renaming macros]],
    5159but CK-macros are much more portable.
    52 The core {{ck}} macro and most CK-macros are implemented using only {{syntax-rules}},
    53 which means they will work on any implementation of R5RS or later.
     60The [[#ck|core {{ck}} macro]] and all the macros in the [[#portable-ck-macros|Portable CK-Macros]] section
     61are implemented using only standard R5RS features,
     62such as {{syntax-rules}} and {{let-syntax}}.
     63This means they will work on any implementation of R5RS or later.
    5464
    5565
     
    6575</enscript>
    6676
    67 As you can see, a CK-macro is a macro that expands into a call to the core {{ck}} macro.
    68 The core {{ck}} macro does some clever rearranging under the hood
    69 to support composition with other CK-macros.
    70 
    71 CK-macros are usually defined using {{syntax-rules}} for maximum portability.
    72 But, it is also possible to write CK-macros using other macro systems,
     77A CK-macro is just a normal macro that expands to a call to the core {{ck}} macro.
     78To be portable, CK-macros are usually written using {{syntax-rules}}.
     79But, you can write CK-macros using other macro systems,
    7380such as CHICKEN's [[/manual/Macros|explicit and implicit renaming macros]],
    74 as long as those macros expand into a call to the core {{ck}} macro.
     81as long your macro eventually expands into a call to the core {{ck}} macro.
    7582
    7683By convention, the names of CK-macros usually start with "c-",
     
    7885But, this naming convention is not required.
    7986
    80 CK-macros treat quoting specially, so you should include {{quote}} in the first argument to {{syntax-rules}}, the list of literal identifiers.
    81 
    82 The first argument to every CK-macro must be the stack, usually called {{s}}.
    83 The stack is used by the core {{ck}} macro to do its clever rearranging.
    84 Your CK-macro should not touch the stack, just pass it through to the core {{ck}} macro.
     87CK-macros treat quoting specially, so you should have {{quote}} in the list of literal identifiers (the first argument to {{syntax-rules}}).
     88You can also have other literal identifiers if needed.
     89
     90Every CK-macro's first argument must be the stack, usually called {{s}}.
     91The stack is used internally by the core {{ck}} macro while recursively expanding macro arguments.
     92Your CK-macro should not touch the stack, only pass it through to the core {{ck}} macro.
    8593
    8694Each {{'input}} is an argument passed to your macro.
    87 The core {{ck}} macro expands the arguments ahead of time (unless the argument is quoted),
     95Your macro can have any number of input arguments, and they can be named whatever you want.
     96They can also be lists or patterns, allowing you to destructure the arguments,
     97as is often done with {{syntax-rules}} macros.
     98
     99The core {{ck}} macro expands the input arguments ahead of time,
    88100so the arguments will always be quoted values by the time your macro is expanded.
    89 Usually CK-macros are defined with their arguments quoted (as above),
    90 so that you can easily extract the unquoted value to use in your macro.
     101Usually CK-macros are defined with their input arguments quoted (as above),
     102so that you can easily destructure the input to use in your macro.
     103You may recall that {{'a}} is translated by the reader to {{(quote a)}}.
     104So, the above example is exactly the same as:
     105
     106<enscript highlight="scheme">
     107(define-syntax c-foo
     108  (syntax-rules (quote)
     109    ((c-foo s (quote input1) (quote input2) ...)
     110     (ck s output))))
     111</enscript>
     112
     113When written in this way, it is easier to see that {{input1}} and {{input2}}
     114are merely placeholders in the {{syntax-rules}} pattern.
     115(This is also why you must tell {{syntax-rules}} that {{quote}} is a literal identifier.
     116Otherwise, {{syntax-rules}} would treat {{quote}} as a placeholder, too.)
    91117
    92118Your macro should transform the {{input}}s in some way to produce the {{output}},
     
    122148
    123149
    124 === Combining CK-macros with non-CK macros
    125 
    126 All CK-macros must evenutally expand to a call to the core {{ck}} macro.
    127 Therefore, many non-CK macros cannot be used ''inside'' CK-macros.
    128 
    129 But, it is always possible to write a non-CK macro which calls invokes a CK-macro.
     150=== Combining CK and non-CK macros
     151
     152The arguments to a CK-macro must either be a quoted value or a call to a CK-macro
     153(i.e. a macro that expands to a call to the core {{ck}} macro).
     154Therefore, most non-CK macros and special forms cannot be used as arguments to a CK-macro.
     155
     156Some non-CK macros can be used in a way that expands into a user-provided expression.
     157It is therefore possible for these non-CK macros to be used as arguments CK-macros,
     158as long as they eventually expand into a call to the core {{ck}} macro.
     159
     160It is possible to write a non-CK macro which invokes a CK-macro via the core {{ck}} macro.
    130161For example, if you are writing a macro for other people to use,
    131162you can create a convenience wrapper macro, like so:
     
    139170</enscript>
    140171
    141 Also, it is always possible for a CK-macro to expand into a call to a non-CK macro as its final result.
     172Also, it is possible for a CK-macro to expand into a call to a non-CK macro as its final result,
     173or as part of the body of its final result.
    142174For example:
    143175
    144176<enscript highlight="scheme">
    145 ;;; Non-CK macro
    146 (define-syntax bar
    147   (syntax-rules ()
    148     ((bar a b c)
    149      (+ a (* b c)))))
    150 
    151 ;;; CK-macro
    152 (define-syntax c-fiz
    153   (syntax-rules (quote)
    154     ((c-fiz s 'a 'b 'c)
    155      (ck s '(bar a b c)))))
    156 
    157 (ck () (c-fiz '1 '2 '3))
    158 ;;; Expands to the expression (bar 1 2 3),
    159 ;;; which expands to the expression (+ 1 (* 2 3)),
    160 ;;; which evaluates to the number 7.
    161 </enscript>
    162 
    163 Finally, some non-CK macros can be used in a way that expands into a user-provided expression.
    164 These non-CK macros can therefore be used ''inside'' CK-macros,
    165 as long as they eventually expand into a call to the core {{ck}} macro.
     177(ck () (c-list 'when (c-list '< '1 '2) (c-list 'print '"Yay!")))
     178;;; Expands to the expression (when (< 1 2) (print "Yay!")).
     179</enscript>
    166180
    167181
     
    177191; s : The stack, used internally by this macro. When initially invoking this macro, {{s}} should be the empty list, e.g. {{(ck () (c-cons '+ '(1 2)))}}.
    178192; 'v : A quoted value. Can be a quoted list, symbol, or other literal value. The quote is necessary, even for literal values like strings, numbers, and booleans.
    179 ; (op ...) : A CK-macro call '''without the s argument''', such as {{(c-cons '+ '(1 2))}}.
     193; (op ...) : A CK-macro call '''without the s argument''', such as {{(c-cons '+ '(1 2))}}. Nested calls are allowed, such as {{(c-cons '+ (c-list '1 '2))}}.
    180194
    181195
     
    184198The CK-macros in this section are defined using only standard R5RS features,
    185199such as {{syntax-rules}} and {{let-syntax}}.
    186 Therefore, these CK-macros will work with any implementation of R5RS or later.
     200So, these CK-macros will work on any implementation of R5RS or later.
     201
    187202
    188203==== General
     
    260275
    261276Conditional branching.
    262 Yields {{FAIL}} if {{TEST}} is {{'#f}} (or an operation that yields {{'#f}}).
    263 Otherwise yields {{PASS}}.
     277If {{TEST}} is {{'#f}}, this yields {{FAIL}}.
     278Otherwise it yields {{PASS}}.
    264279
    265280Due to the way the CK machine works, both branches will be expanded,
     
    268283(e.g. because the branches are complex and slow to expand,
    269284or because it would be an error to expand the unneeded branch),
    270 use {{c-if/q}} instead.
     285use {{c-if*}} instead.
    271286
    272287Analogous to
     
    286301
    287302
    288 <syntax>(c-if/q 'TEST 'PASS 'FAIL)  →  PASS or FAIL</syntax>
    289 
    290 Similar to {{c-if}}, except that all the arguments must have an extra level of quoting,
     303<syntax>(c-if* TEST 'PASS 'FAIL)  →  PASS or FAIL</syntax>
     304
     305Similar to {{c-if}}, except that the branches must have an extra level of quoting,
    291306and only one branch will be expanded.
    292307This is more similar to how {{if}} behaves, but it is a bit awkward to use.
    293308
    294309Analogous to
    295 {{(lambda (test pass fail) (if (eval test) (eval pass) (eval fail)))}}
    296 
    297 <enscript highlight="scheme">
    298 (ck () (c-quote (c-if '(c-pair? '(x))
     310{{(lambda (test pass fail) (if test (eval pass) (eval fail)))}}
     311
     312<enscript highlight="scheme">
     313(ck () (c-quote (c-if (c-pair? '(x))
    299314                      '(c-car '(x))
    300315                      ''not-pair))
    301316;; ==> 'x
    302317
    303 (ck () (c-quote (c-if '(c-pair? 'x)
     318(ck () (c-quote (c-if (c-pair? 'x)
    304319                      '(c-car 'x)
    305320                      ''not-pair))
     
    315330
    316331Roughly analogous to {{or}}, except all arguments are expanded.
    317 If you only want to expand the arguments that are needed, use {{c-or/q}} instead.
    318 
    319 
    320 <syntax>(c-or/q 'X ...)  →  item or '#f</syntax>
     332If you only want to expand the arguments that are needed, use {{c-or*}} instead.
     333
     334
     335<syntax>(c-or* 'X ...)  →  item or '#f</syntax>
    321336
    322337Similar to {{c-or}}, except that all the arguments must have an extra level of quoting,
     
    332347
    333348Roughly analogous to {{and}}, except all arguments are expanded.
    334 If you only want to expand the arguments that are needed, use c-and/q instead.
    335 
    336 
    337 <syntax>(c-and/q X ...)  →  item or '#f</syntax>
     349If you only want to expand the arguments that are needed, use {{c-and*}} instead.
     350
     351
     352<syntax>(c-and* X ...)  →  item or '#f</syntax>
    338353
    339354Similar to {{c-and}}, except that all the arguments must have an extra level of quoting,
     
    344359<syntax>(c-null? X)  →  '#t or '#f</syntax>
    345360
    346 Yields {{'#t}} if {{X}} is the empty list, '().
     361Yields {{'#t}} if {{X}} is the empty list, {{'()}}.
    347362Otherwise yields {{'#f}}.
    348363Analogous to {{null?}}.
     
    360375Opposite of {{c-pair?}}.
    361376Analogous to {{not-pair?}} from SRFI-1.
     377
     378
     379<syntax>(c-vector? X)  →  '#t or '#f</syntax>
     380
     381Yields {{'#t}} if {{X}} is a vector.
     382Otherwise yields {{'#f}}.
     383Analogous to {{vector?}}.
     384
     385<enscript highlight="scheme">
     386(ck () (c-quote (c-vector? '#(a))))
     387;; ==> '#t
     388</enscript>
    362389
    363390
     
    379406Roughly analogous to {{eq?}},
    380407except it only works (portably) with symbols.
    381 Based on {{symbol-eq?}} from the article.
     408Based on {{symbol-eq?}} from the original implementation.
    382409
    383410
    384411<syntax>(c-sym-equal? X Y)  →  '#t or '#f</syntax>
    385412
    386 Similar to c-sym-eq?, except it recursively compares lists and pairs.
     413Similar to {{c-sym-eq?}}, except it recursively compares
     414pairs, lists, and vectors.
    387415
    388416Roughly analogous to {{equal?}},
    389 except it only works (portably) with symbols, lists of symbols, and pairs of symbols.
     417except it only works (portably) with symbols, pairs, lists, vectors,
     418and nested combinations of those things.
    390419
    391420
     
    411440<syntax>(c-list X ...)  →  list</syntax>
    412441
    413 Yields a list with the given arguments.
     442Yields a list containing the given items.
    414443Analogous to {{list}}.
     444
     445<enscript highlight="scheme">
     446(ck () (c-quote (c-list)))
     447;; ==> '()
     448(ck () (c-quote (c-list 'a 'b 'c)))
     449;; ==> '(a b c)
     450</enscript>
    415451
    416452
     
    420456Analogous to {{car}}.
    421457
     458<enscript highlight="scheme">
     459(ck () (c-quote (c-car '(a . b))))
     460;; ==> 'a
     461
     462(ck () (c-quote (c-car '(a b))))
     463;; ==> 'a
     464</enscript>
     465
    422466
    423467<syntax>(c-cdr P)  →  tail</syntax>
     
    425469Yields the tail of the given pair.
    426470Analogous to {{cdr}}.
     471
     472<enscript highlight="scheme">
     473(ck () (c-quote (c-cdr '(a . b))))
     474;; ==> 'b
     475
     476(ck () (c-quote (c-cdr '(a b))))
     477;; ==> '(b)
     478</enscript>
    427479
    428480
     
    486538Drops a predefined number of items from the front of the given list.
    487539Fails if the list is too short.
     540See also {{c-udrop}}.
    488541
    489542Analogous to {{(drop L N)}} from SRFI-1.
    490 See also {{c-udrop}}.
    491543
    492544<enscript highlight="scheme">
     
    507559Yields a list containing a predefined number of items from the front of the given list.
    508560Fails if the list is too short.
     561See also {{c-utake}}.
    509562
    510563Analogous to {{(take L N)}} from SRFI-1.
    511 See also {{c-utake}}.
    512564
    513565<enscript highlight="scheme">
     
    526578Analogous to {{reverse}}.
    527579
     580<enscript highlight="scheme">
     581(ck () (c-quote (c-reverse '(a b c))))
     582;; ==> '(c b a)
     583</enscript>
     584
    528585
    529586<syntax>(c-suffix L X ...)  →  list</syntax>
    530587
    531588Yields the given list with the extra arguments added to the end.
    532 {{(c-suffix '(1 2) '3 '4)}} is equivalent to {{(c-append '(1 2) '(3 4))}}.
    533 
    534 
    535 <syntax>(c-append L1 L2)  →  list</syntax>
    536 
    537 Appends the two given lists.
     589
     590<enscript highlight="scheme">
     591(ck () (c-quote (c-suffix '(a) 'b 'c)))
     592;; ==> '(a b c)
     593</enscript>
     594
     595
     596<syntax>(c-append L ...)  →  list</syntax>
     597
     598Appends the given lists.
    538599Analogous to {{append}}.
    539600
    540601<enscript highlight="scheme">
     602(ck () (c-quote (c-append)))
     603;; ==> '()
     604
     605(ck () (c-quote (c-append '(+) (c-append '(1) '(2)))))
     606;; ==> '(+ 1 2)
     607
    541608(ck () (c-quote (c-append '(define foo) '((+ 1 2)))))
    542609;; ==> '(define foo (+ 1 2 3))
    543 
    544 (ck () (c-quote (c-append '(+) (c-append '(1) '(2)))))
    545 ;; ==> '(+ 1 2)
    546610</enscript>
    547611
     
    554618The operation may have leading arguments.
    555619
    556 Analogous to {{append-map}} from SFRI-1.
    557 This was named {{c-concatMap}} in the article.
     620Analogous to {{append-map}} from SFRI-1, but only accepts one list.
     621This was named {{c-concatMap}} in the original implementation.
    558622
    559623<enscript highlight="scheme">
     
    567631Yields a list by calling the quoted operation on each item in the given list.
    568632The operation may have leading arguments.
    569 Analogous to {{map}}.
     633Analogous to {{map}}, but only accepts one list.
    570634
    571635<enscript highlight="scheme">
     
    580644with each item from the list plus the previous result.
    581645
    582 The operation is first called with two arguments,
    583 the first item of the list and the initial value.
    584 Then, the operation is called with the next item of the list and the previous result.
    585 
    586 If list is empty, yields {{INIT}}.
    587 
    588 Analogous to {{fold}} from SRFI-1.
     646If the list is empty, yields {{INIT}}.
     647Otherwise, the operation is first called with two arguments:
     648the first item of the list, and INIT.
     649Then, the operation is repeatedly called with the next item of the list and the previous result,
     650until it reaches the end of the list.
     651Yields the final result.
     652
     653Analogous to {{fold}} from SRFI-1, but only accepts one list.
     654
     655<enscript highlight="scheme">
     656(ck () (c-quote (c-fold '(c-cons) '(x) '())))
     657;; ==> '(x)
     658(ck () (c-quote (c-fold '(c-cons) '(x) '(a b c d e f))))
     659;; ==> '(f e d c b a x)
     660</enscript>
    589661
    590662
     
    595667Analogous to {{filter}} from SRFI-1.
    596668
     669<enscript highlight="scheme">
     670(ck () (c-quote (c-filter '(c-pair?)
     671                          '(a (b . c) 1 (d e) #t))))
     672;; ==> '((b . c) (d e))
     673</enscript>
     674
    597675
    598676<syntax>(c-remove '(OP ...) L)  →  list</syntax>
    599677
    600 Opposite of c-filter.
     678Opposite of {{c-filter}}.
    601679Discards items that pass the test, keeps items that fail the test.
    602680Analogous to {{remove}} from SRFI-1.
    603681
     682<enscript highlight="scheme">
     683(ck () (c-quote (c-remove '(c-pair?)
     684                          '(a (b . c) 1 (d e) #t))))
     685;; ==> '(a 1 #t)
     686</enscript>
     687
    604688
    605689<syntax>(c-find '(OP ...) L)  →  item or '#f</syntax>
    606690
    607 Yields the first item in the given list that passes the predicate operation
    608 (i.e. the predicate yields a non-{{'#f}} value).
    609 Yields {{'#f}} if no items pass the predicate.
     691Searches the list for the first item that passes the predicate operation
     692(i.e. the predicate yields a non-{{'#f}} value),
     693then yields that item.
     694Yields {{'#f}} if no item passes the predicate.
    610695
    611696Analogous to {{find}} from SRFI-1.
    612697
     698<enscript highlight="scheme">
     699(ck () (c-quote (c-find '(c-pair?)
     700                        '(a (b . c) 1 (d e) #t))))
     701;; ==> '(b . c)
     702</enscript>
     703
    613704
    614705<syntax>(c-find-tail '(OP ...) L)  →  pair or '#f</syntax>
    615706
    616 Yields the first pair in the list for which the head of the pair passes the predicate operation
    617 (i.e. the predicate yields a non-{{'#f}} value).
    618 Yields {{'#f}} if no items pass the predicate.
     707Searches the list for the first item that passes the predicate operation
     708(i.e. the predicate yields a non-{{'#f}} value),
     709then yields the tail of the list starting with that item.
     710Yields {{'#f}} if no item passes the predicate.
    619711
    620712Analogous to {{find-tail}} from SRFI-1.
    621713
    622 
    623 <syntax>(c-sym-member X L)  →  '#t or '#f</syntax>
    624 
    625 Yields {{'#t}} if the list contains the given symbol, list of symbols,
    626 or pair of symbols, using {{c-sym-equal?}} for comparison.
    627 Otherwise yields {{'#f}}.
    628 
    629 Roughly analogous to {{member}}.
     714<enscript highlight="scheme">
     715(ck () (c-quote (c-find-tail '(c-pair?)
     716                             '(a (b . c) 1 (d e) #t))))
     717;; ==> '((b . c) 1 (d e) #t)
     718</enscript>
     719
     720
     721<syntax>(c-member X L)  →  '#t or '#f</syntax>
     722<syntax>(c-member X L '(OP ...))  →  '#t or '#f</syntax>
     723
     724Searches the list for the first occurance of {{X}},
     725then yields the tail of the list starting with that item.
     726Yields {{'#f}} if the list does not contain {{X}}.
     727
     728Uses {{'(OP ...)}} for comparison,
     729or {{'(c-sym-equal?)}} if the operation is omitted.
     730So by default, {{X}} must be a symbol, list, pair, vector,
     731or nested combination of those things.
     732
     733Same as {{(c-find-tail '(OP ... X) L)}}.
     734Roughly analogous to {{member}} except for the default allowed types.
     735
     736<enscript highlight="scheme">
     737(ck () (c-quote (c-member 'b '(a b c))))
     738;; ==> '(b c)
     739
     740(ck () (c-quote (c-member 'x '(a b c))))
     741;; ==> '#f
     742
     743(ck () (c-quote (c-member '(a b c)
     744                          '((a) (x y z) (a b))
     745                          '(c-u=))))
     746;; ==> '((x y z) (a b))
     747;; Because (c-u= '(a b c) '(x y z)) yields '#t
     748</enscript>
    630749
    631750
     
    638757
    639758Analogous to {{any}} from SRFI-1.
     759
     760<enscript highlight="scheme">
     761(ck () (c-quote (c-any '(c-pair?) '())))
     762;; ==> '#f
     763(ck () (c-quote (c-any '(c-pair?) '(a b c))))
     764;; ==> '#f
     765(ck () (c-quote (c-any '(c-pair?) '(a (b . c)))))
     766;; ==> '#t
     767
     768(ck () (c-quote (c-any '(c-cons 'z) '(a b c))))
     769;; ==> '(1 . a)
     770;; Because (c-cons 'z 'a) yields a value that is not '#f.
     771</enscript>
    640772
    641773
     
    650782Analogous to {{every}} from SRFI-1.
    651783
     784<enscript highlight="scheme">
     785(ck () (c-quote (c-every '(c-pair?) '())))
     786;; ==> '#t
     787(ck () (c-quote (c-every '(c-pair?) '(a (b . c)))))
     788;; ==> '#f
     789(ck () (c-quote (c-every '(c-pair?) '((a . b) (b . c)))))
     790;; ==> '#t
     791
     792(ck () (c-quote (c-every '(c-cons 'z) '(a b c))))
     793;; ==> '(z . c)
     794;; Because all results were non-'#f and (c-cons 'z 'c) was the final operation.
     795</enscript>
     796
    652797
    653798<syntax>(c-assoc KEY ALIST)  →  pair or '#f</syntax>
    654799<syntax>(c-assoc KEY ALIST '(OP ...))  →  pair or '#f</syntax>
    655800
    656 Yields the first pair in {{ALIST}} whose car matches {{KEY}},
    657 or {{'#f}} if no match is found.
     801Searches {{ALIST}} for the first pair whose car matches {{KEY}},
     802then yields that pair.
     803Yields {{'#f}} if no match is found.
     804{{ALIST}} must be an association list, i.e. a list of pairs.
     805
    658806Uses {{'(OP ...)}} for comparison,
    659807or {{'(c-sym-equal?)}} if {{'(OP ...)}} is omitted.
     
    661809Analogous to {{assoc}} from SRFI-1.
    662810
     811<enscript highlight="scheme">
     812(ck () (c-quote (c-assoc 'x '((a . 1) (b . 2) (a . 3)))))
     813;; ==> '#f
     814(ck () (c-quote (c-assoc 'a '((a . 1) (b . 2) (a . 3)))))
     815;; ==> '(a . 1)
     816(ck () (c-quote (c-assoc '(a) '((a . 1) (b . 2) ((a) . 3)))))
     817;; ==> '((a) . 3)
     818</enscript>
     819
    663820
    664821<syntax>(c-alist-delete KEY ALIST)  →  list</syntax>
     
    666823
    667824Removes all pairs in {{ALIST}} whose car matches {{KEY}}.
     825{{ALIST}} must be an association list, i.e. a list of pairs.
     826
    668827Uses {{'(OP ...)}} for comparison,
    669828or {{'(c-sym-equal?)}} if {{'(OP ...)}} is omitted.
    670829
    671830Analogous to {{alist-delete}} from SRFI-1.
    672 Based on {{c-delete-assoc}} from the article.
     831Based on {{c-delete-assoc}} from the original implementation.
     832
     833<enscript highlight="scheme">
     834(ck () (c-quote (c-alist-delete 'a '((a . 1) (b . 2) (a . 3) (c . 4)))))
     835;; ==> '((b . 2) (c . 4)
     836(ck () (c-quote (c-alist-delete '(a) '((a . 1) (b . 2) ((a) . 3)))))
     837;; ==> '((a . 1) (b . 2))
     838</enscript>
     839
     840
     841==== Vector Processing
     842
     843<syntax>(c-vector X ...)  →  vector</syntax>
     844
     845Yields a vector containing the given items.
     846Analogous to {{vector}}.
     847
     848
     849<syntax>(c-list->vector L)  →  vector</syntax>
     850
     851Yields a vector containing the same items as the given list.
     852Analogous to {{list->vector}} from SRFI-43.
     853
     854
     855<syntax>(c-vector->list V)  →  list</syntax>
     856
     857Yields a list containing the same items as the given vector.
     858Analogous to {{vector->list}} from SRFI-43.
     859
     860
     861<syntax>(c-vector-reverse V)  →  vector</syntax>
     862
     863Yields the given vector in reverse order.
     864Similar to {{vector-reverse-copy}} from SRFI-43,
     865but does not take a start or end argument.
     866
     867
     868<syntax>(c-vector-suffix V X ...)  →  vector</syntax>
     869
     870Yields the given vector with the extra arguments added to the end.
     871
     872<enscript highlight="scheme">
     873(ck () (c-quote (c-vector-suffix '#(a b) 'c 'd)))
     874;; ==> '#(a b c d)
     875</enscript>
     876
     877
     878<syntax>(c-vector-append V ...)  →  vector</syntax>
     879
     880Appends the given vectors.
     881Analogous to {{vector-append}} from SRFI-43,
     882but only accepts two vectors.
     883
     884<enscript highlight="scheme">
     885(ck () (c-quote (c-vector-append)))
     886;; ==> '#()
     887
     888(ck () (c-quote (c-vector-append '#(a b) '#(c d) '#(e f))))
     889;; ==> '#(a b c d e f)
     890</enscript>
     891
     892
     893<syntax>(c-vector-map '(OP ...) V)  →  vector</syntax>
     894
     895Yields a vector by calling the quoted operation on each item in the given vector.
     896The operation may have leading arguments.
     897
     898Analogous to {{vector-map}} from SRFI-43, but only accepts one vector.
    673899
    674900
     
    693919otherwise yields {{'#f}}.
    694920
     921<enscript highlight="scheme">
     922(ck () (c-quote (c-u= '(a b c) '(a b c))))
     923;; ==> '#t
     924(ck () (c-quote (c-u= '(1 2 3) '(a b c))))
     925;; ==> '#t
     926(ck () (c-quote (c-u= '(1 2) '(a b c))))
     927;; ==> '#f
     928</enscript>
     929
    695930
    696931<syntax>(c-u< U1 U2)  →  '#t or '#f</syntax>
     
    700935otherwise yields {{'#f}}.
    701936
     937<enscript highlight="scheme">
     938(ck () (c-quote (c-u< '(1 2) '(a b c))))
     939;; ==> '#t
     940(ck () (c-quote (c-u< '(1 2 3) '(a b c))))
     941;; ==> '#f
     942</enscript>
     943
    702944
    703945<syntax>(c-u<= U1 U2)  →  '#t or '#f</syntax>
     
    707949otherwise yields {{'#f}}.
    708950
     951<enscript highlight="scheme">
     952(ck () (c-quote (c-u<= '(1 2) '(a b c))))
     953;; ==> '#t
     954(ck () (c-quote (c-u<= '(1 2 3) '(a b c))))
     955;; ==> '#t
     956(ck () (c-quote (c-u<= '(1 2 3 4) '(a b c))))
     957;; ==> '#f
     958</enscript>
     959
    709960
    710961<syntax>(c-u> U1 U2)  →  '#t or '#f</syntax>
     
    714965otherwise yields {{'#f}}.
    715966
     967<enscript highlight="scheme">
     968(ck () (c-quote (c-u> '(1 2 3 4) '(a b c))))
     969;; ==> '#t
     970(ck () (c-quote (c-u> '(1 2 3) '(a b c))))
     971;; ==> '#f
     972</enscript>
     973
    716974
    717975<syntax>(c-u>= U1 U2)  →  '#t or '#f</syntax>
     
    721979otherwise yields {{'#f}}.
    722980
     981<enscript highlight="scheme">
     982(ck () (c-quote (c-u>= '(1 2 3 4) '(a b c))))
     983;; ==> '#t
     984(ck () (c-quote (c-u>= '(1 2 3) '(a b c))))
     985;; ==> '#t
     986(ck () (c-quote (c-u>= '(1 2) '(a b c))))
     987;; ==> '#f
     988</enscript>
     989
    723990
    724991<syntax>(c-uzero? U)  →  '#t or '#f</syntax>
     
    728995Same as {{c-null?}}.
    729996
     997<enscript highlight="scheme">
     998(ck () (c-quote (c-uzero? '())))
     999;; ==> '#t
     1000(ck () (c-quote (c-uzero? '(a))))
     1001;; ==> '#f
     1002</enscript>
     1003
    7301004
    7311005<syntax>(c-ueven? U)  →  '#t or '#f</syntax>
     
    7351009(i.e. a multiple of 2), otherwise yields {{'#f}}.
    7361010
     1011<enscript highlight="scheme">
     1012(ck () (c-quote (c-ueven? '())))
     1013;; ==> '#t
     1014(ck () (c-quote (c-ueven? '(a))))
     1015;; ==> '#f
     1016(ck () (c-quote (c-ueven? '(a b))))
     1017;; ==> '#t
     1018</enscript>
     1019
    7371020
    7381021<syntax>(c-uodd? U)  →  '#t or '#f</syntax>
     
    7421025(i.e. not a multiple of 2), otherwise yields {{'#f}}.
    7431026
     1027<enscript highlight="scheme">
     1028(ck () (c-quote (c-uodd? '())))
     1029;; ==> '#f
     1030(ck () (c-quote (c-uodd? '(a))))
     1031;; ==> '#t
     1032(ck () (c-quote (c-uodd? '(a b))))
     1033;; ==> '#f
     1034</enscript>
     1035
    7441036
    7451037<syntax>(c-u+ U1 U2)  →  list</syntax>
     
    7471039Unary addition.
    7481040Same as {{c-append}}.
    749 This was named {{c-add}} in the article.
     1041This was named {{c-add}} in the original implementation.
     1042
     1043<enscript highlight="scheme">
     1044(ck () (c-quote (c-u+ '(a b) '(c))))
     1045;; ==> '(a b c)
     1046</enscript>
    7501047
    7511048
     
    7581055so this yields '() if the second list is equal or longer than the first.
    7591056
     1057<enscript highlight="scheme">
     1058(ck () (c-quote (c-u- (c-list 'a 'b 'c 'd) '(x y))))
     1059;; ==> '(c d)
     1060
     1061(ck () (c-quote (c-u- (c-list 'a 'b) (c-list 'x 'y 'z))))
     1062;; ==> '()
     1063;; Because negative numbers cannot be represented in unary.
     1064</enscript>
     1065
    7601066
    7611067<syntax>(c-u* U1 U2)  →  list</syntax>
     
    7651071repeated once for every item in the second list.
    7661072
    767 Based on {{c-mul}} from the article,
     1073Based on {{c-mul}} from the original implementation,
    7681074except the symbol 'u has no special significance,
    7691075and result is made from duplicating the first list.
     1076
     1077<enscript highlight="scheme">
     1078(ck () (c-quote (c-u* '(a b) '(c d e))))
     1079;; ==> '(a b a b a b)
     1080</enscript>
    7701081
    7711082
     
    7801091and the remainder will contain the tail of the first list.
    7811092Division by zero (empty list) is a syntax error.
     1093
     1094<enscript highlight="scheme">
     1095(ck () (c-quote (c-u/ '(a b c d e f g h i j k)
     1096                      '(x y z))))
     1097;; ==> '((g d a) (j k))
     1098;; Because 11 / 3 = 3 with a remainder of 2.
     1099</enscript>
    7821100
    7831101
     
    7911109This was named {{c-fact}} in the original source.
    7921110
     1111<enscript highlight="scheme">
     1112(ck () (c-quote (c-ufactorial '(a b c))))
     1113;; ==> '(a b c a b c)
     1114;; Because 3! = 6.
     1115</enscript>
     1116
    7931117
    7941118<syntax>(c-udrop L U)  →  list</syntax>
     
    7971121where U is a unary number.
    7981122
     1123Same as {{c-u-}}.
    7991124Analogous to {{drop}} from SRFI-1,
    8001125but uses unary numbers,
    8011126and yields empty list if the list is too short.
    8021127
     1128<enscript highlight="scheme">
     1129(ck () (c-quote (c-udrop (c-list 'a 'b 'c 'd) '(x y))))
     1130;; ==> '(c d)
     1131(ck () (c-quote (c-udrop (c-list 'a 'b) (c-list 'x 'y 'z))))
     1132;; ==> '()
     1133</enscript>
     1134
    8031135
    8041136<syntax>(c-utake L U)  →  list</syntax>
     
    8101142but uses unary numbers,
    8111143and yields the entire list if it is too short.
     1144
     1145<enscript highlight="scheme">
     1146(ck () (c-quote (c-utake '(a b c d) '(x y z))))
     1147;; ==> '(a b c)
     1148(ck () (c-quote (c-utake '(a b) '(x y z))))
     1149;; ==> '(a b)
     1150</enscript>
Note: See TracChangeset for help on using the changeset viewer.