Changeset 37407 in project


Ignore:
Timestamp:
03/18/19 01:38:11 (16 months ago)
Author:
John Croisant
Message:

Update ck-macros wiki for version 0.3.0.

File:
1 edited

Legend:

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

    r37322 r37407  
    66"[[http://okmij.org/ftp/Scheme/macros.html#ck-macros|Applicative syntax-rules: macros that compose better]]"
    77by Oleg Kiselyov.
    8 This egg provides the core {{ck}} macro,
     8This egg provides an enhanced version of the core {{ck}} macro,
    99many useful (and some not-so-useful) predefined CK-macros,
    1010the {{ck-wrapper}} procedure, and many wrappers of R5RS procedures.
     
    1818; Maintainer: [[/users/john-croisant|John Croisant]]
    1919; Based on work by: Oleg Kiselyov
    20 ; License: Public Domain
     20; License: Released to the public domain. See [[http://unlicense.org]]
    2121
    2222
     
    2727=== Version History
    2828
     29; 0.3.0 (2019-03-17) : Enhanced the core {{ck}} macro to support quasiquotation. Added some new portable CK-macros. Clarified license.
    2930; 0.2.0 (2019-02-28) : Ported to CHICKEN 5. Added {{ck-wrapper}} and many R5RS wrappers. Added some new portable CK-macros. Breaking changes to {{c-apply}}. Renamed some CK-macros.
    3031; 0.1.1 (2016-02-07) : Fixed {{c-append}} and {{c-vector-append}} failing when given one argument.
     
    7677=== How to write CK-macros
    7778
    78 (Note: If you don't care about strict R5RS portability,
     79(Note: If you do not require strict R5RS portability,
    7980the easiest way to create a CK-macro is with [[#ck-wrapper|{{ck-wrapper}}]].)
    8081
     
    192193
    193194
    194 === Troubleshooting
    195 
    196 CK-macros push the Scheme macro system in unusual ways,
    197 so unfortunately they are not very user-friendly.
    198 
    199 One common error you may see is, "no rule matches form".
    200 This often indicates that you forgot to quote a value somewhere.
     195=== Partial application
     196
     197Many CK-macros, such as {{c-compare}} and {{c-map1}}, take one or more operations as an argument.
     198This is denoted with {{'(OP ...)}} in the CK-macro's signature.
     199For example, {{c-map1}} takes an operation which it applies to every element of the list:
     200
     201<enscript highlight="scheme">
     202(ck () (c-quote (c-map1 '(c-vector) '(2 3 4))))
     203;; ==> '(#(2) #(3) #(4))
     204
     205;; Equivalent to:
     206(ck () (c-quote (c-list (c-vector '2)
     207                        (c-vector '3)
     208                        (c-vector '4))))
     209</enscript>
     210
     211All CK-macros which take an operation allow '''partial application''',
     212by providing initial arguments that should be used when performing the operation:
     213
     214<enscript highlight="scheme">
     215(ck () (c-quote (c-map1 '(c-vector 'x 'y) '(2 3 4))))
     216;; ==> '(#(x y 2) #(x y 3) #(x y 4))
     217
     218;; Equivalent to:
     219(ck () (c-quote (c-list (c-vector 'x 'y '2)
     220                        (c-vector 'x 'y '3)
     221                        (c-vector 'x 'y '4))))
     222</enscript>
     223
     224You can even build up complex operations
     225by partially applying {{c-compose}} or {{c-rcompose}},
     226even with partially applied operations as the initial arguments!
     227
     228<enscript highlight="scheme">
     229(ck () (c-quote (c-map1 '(c-rcompose '((c-* '10)
     230                                       (c-number->string)
     231                                       (c-string-append '"foo")
     232                                       (c-string->symbol)))
     233                        '(1 2 3))))
     234;; ==> '(foo10 foo20 foo30)
     235</enscript>
     236
     237
     238=== Quasiquotation
     239
     240In '''version 0.3.0 and later''', the core {{ck}} macro supports quasiquotation.
     241Internally, {{(quasiquote x)}} (also written as {{`x}})
     242is converted into {{(c-quasiquote 'x)}},
     243a call to the {{c-quasiquote}} CK-macro, which handles unquoting.
     244
     245Quasiquotation can be used as the argument to the core {{ck}} macro itself,
     246and/or in arguments to CK-macros.
     247This is useful for assembling mostly-literal forms, lists, and vectors:
     248
     249<enscript highlight="scheme">
     250(ck () `(define (foo) (list ,@(c-list '1 '2) ,(c-vector '3))))
     251;; ==> (define (foo) (list 1 2 #(3)))
     252
     253(ck () (c-vector-reverse `#(1 ,@(c-list '2 '3))))
     254;; ==> #(3 2 1)
     255</enscript>
     256
     257
     258=== Debugging
     259
     260CK-macros utilize the Scheme macro system in unusual ways,
     261so they are sometimes more difficult to debug than typical Scheme code.
     262
     263The most common error message when using CK-macros is "no rule matches form".
     264This usually indicates one of two problems:
     265
     266* If the error message shows a call to {{ck}}, you are probably missing a quote.
     267* If the error message shows a call to a CK-macro like {{c-cons}},
     268  you probably passed the wrong number or type of arguments.
     269
     270==== Missing quote
     271
    201272As explained in the section [[#how-to-write-ck-macros|How to write CK-macros]],
    202273all values must be quoted,
     
    208279 Syntax error: no rule matches form
    209280 
    210          (ck38782 (((c-not))) #t)
    211 
    212 The solution is to quote the {{#t}}, like this: {{(ck () (c-not '#t))}}
     281         (ck123 (((c-not))) #t)
     282
     283In the error message above, {{ck123}} is the core {{ck}} macro.
     284The Scheme macro system has appended a unique number for macro hygiene.
     285The number will vary, and is usually not important to pay attention to.
     286
     287Because this error message shows a call to {{ck}},
     288we know it probably indicates a missing quote.
     289Indeed, the solution is to quote the {{#t}}, like this: {{(ck () (c-not '#t))}}
     290
     291Sometimes the error is not so obvious, and you need to read the stack
     292to find clues about what the problem is and where in the code it happened.
     293
     294
     295==== Reading error messages
     296
     297As explained in the section [[#how-to-write-ck-macros|How to write CK-macros]],
     298the first argument to the core {{ck}} macro is always the stack.
     299The stack is a list of pending operations and their arguments.
     300The first item in the stack is the most recent (inner-most) pending operation,
     301which will be resumed once the current operation is complete.
     302The last item in the stack is the oldest (outer-most) pending operation.
     303
     304You can use this like a "stack trace" to locate where in the code an error occurred.
     305Consider the following code, which has a mistake somewhere:
     306
     307<enscript highlight="scheme">
     308(ck () (x 'x1
     309          'x2
     310          (y (c-cons 'y1 'y2)
     311             (z 'z1
     312                z2
     313                'z3)
     314             'y3
     315             (c-list 'y4))))
     316</enscript>
     317
     318When compiled, we see an error like this:
     319
     320 Syntax error: no rule matches form
     321 
     322         (ck67 (((z (quote65 z1)) (quote z3)) ((y (quote56 (y1 . y2))) (quote y3) (c-list (quote y4))) ((x (quote30 x1) (quote33 x2)))) z2)
     323
     324That looks pretty scary, but it's easier to understand if we reformat it a little:
     325
     326<enscript highlight="scheme">
     327(ck (((z 'z1) 'z3)
     328     ((y '(y1 . y2)) 'y3 (c-list 'y4))
     329     ((x 'x1 'x2)))
     330    z2)
     331</enscript>
     332
     333The first place to look is at the bottom, the last argument to {{ck}}.
     334That is the expression which is currently being evaluated,
     335and therefore is the immediate cause of the error: we forgot to quote {{z2}}.
     336
     337In this case, we only use the expression {{z2}} in one place,
     338so it is easy to locate exactly where the problem is in our code.
     339But it's not always possible to tell where the error occurred
     340just by looking at what argument is currently being evaluated.
     341Sometimes you need to look at the stack, which is the first argument to {{ck}}.
     342
     343In this example we know that the error occurred while evaluating arguments to {{z}},
     344because that is at the top of the stack.
     345We know the value {{'z1}} has already been evaluated
     346because it is inside the list with {{z}}.
     347The expression {{'z3}} is outside the list, still waiting to be evaluated,
     348after we finish evaluating the current argument.
     349
     350Moving down one level of the stack, we can see that before calling {{z}},
     351we were evaluating arguments to {{y}}.
     352The value {{'(y1 . y2)}} is inside the list with {{y}},
     353so we know it has already been evaluated;
     354it came from the expression {{(c-cons 'y1 'y2)}}.
     355The expressions {{'y3}} and {{(c-list 'y4)}} are outside the list,
     356waiting to be evaluated after we finish evaluating the call to {{z}}.
     357
     358And moving one more level down the stack, we were evaluating arguments to {{x}}.
     359The values {{'x1}} and {{'x2}} have already been evaluated,
     360and there are no expressions waiting to be evaluated.
     361The final argument in our call to {{x}} would be the result of the call to {{y}},
     362which is currently in the process of being evaluated.
     363
     364
     365==== Errors inside CK-macro calls
     366
     367Sometimes a "no rule matches form" error will occur
     368while evaluating a call to some CK-macro like {{c-cons}},
     369not a call to the core {{ck}} macro.
     370This often indicates that the wrong number or type of arguments
     371were passed to the CK-macro:
     372
     373<enscript highlight="scheme">
     374(ck () (c-quote (c-list '1 (c-cons '2 '3 '4) '5)))
     375</enscript>
     376
     377 Syntax error: no rule matches form
     378 
     379         (c-cons (((c-list (quote36 1)) (quote 5)) ((c-quote))) (quote45 2) (quote48 3) (quote51 4))
     380
     381Notice that the error shows a call to {{c-cons}},
     382not {{ck}} like it did in the examples above.
     383That indicates that each of the arguments to {{c-cons}} was evaluated with no errors,
     384but there is some problem with the call to {{c-cons}} itself.
     385
     386Like before, we can reformat the error output to make it easier to understand:
     387
     388<enscript highlight="scheme">
     389(c-cons (((c-list '1) '5)
     390         ((c-quote)))
     391        '2
     392        '3
     393        '4)
     394</enscript>
     395
     396We can see that the error occurred while evaluating a call to {{c-cons}}
     397with three arguments: {{'2}}, {{'3}}, and {{'4}}.
     398The problem is that we passed too many arguments to {{c-cons}}.
     399
     400Also, because the first argument to every CK-macro is the stack,
     401we can read the stack to see where in the code the error happened.
     402We can see that, before we started evaluating {{c-cons}},
     403we were evaluating arguments to {{c-list}}.
     404And before that, we were evaluating {{c-quote}}.
     405
     406The error can also occur if you pass the wrong type of argument:
     407
     408<enscript highlight="scheme">
     409(ck () (c-quote (c-vector->list '(1 2 3))))
     410</enscript>
     411
     412 Syntax error: no rule matches form
     413 
     414         (c-vector->list (((c-quote))) (quote36 (1 2 3)))
     415
     416In this example, {{c-vector->list}} expects to be passed a vector,
     417but we passed it a list.
    213418
    214419
     
    266471It is believed to be impossible to fix {{c-sym-eq?}} in a portable way,
    267472so it is recommended that you avoid using it or {{c-sym-equal?}} if possible.
    268 If you don't care about strict R5RS portability,
     473If you do not require strict R5RS portability,
    269474you should use the non-portable wrappers {{c-eq?}} and {{c-equal?}} instead.
    270475
     
    272477=== ck
    273478
    274 <syntax>(ck s 'v)</syntax>
    275 <syntax>(ck s (op ...))</syntax>
     479<syntax>(ck s 'VAL)</syntax>
     480<syntax>(ck s `VAL)</syntax>
     481<syntax>(ck s (OP ...))</syntax>
    276482
    277483This is the core {{ck}} macro, which implements the CK abstract machine.
    278 This macro's public interface has two shapes:
    279 one with a quoted value, and one with a CK-macro call.
     484In '''version 0.3.0 and later''', this macro has been enhanced to support
     485[[#quasiquotation|quasiquotation]].
     486
     487This macro's public interface has three shapes:
     488with a quoted value, with a quasiquoted value, and with a CK-macro call.
    280489
    281490; 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)))}}.
    282 ; '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.
    283 ; (op ...) : A CK-macro call '''without the s argument''', such as {{(c-cons '+ '(1 2))}}.
     491; 'VAL : 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.
     492; `VAL : A [[#quasiquotation|quasiquoted]] value. This is syntactic sugar for {{(c-quasiquote 'VAL)}}.
     493; (OP ...) : A CK-macro call '''without the s argument''', such as {{(c-cons '+ '(1 2))}}.
    284494Nested calls are allowed, such as {{(c-cons '+ (c-list '1 '2))}}.
    285495
     
    361571
    362572
     573<syntax>(c-quasiquote X)  →  result</syntax>
     574
     575Implements [[#quasiquotation|quasiquotation]].
     576Added in '''version 0.3.0'''.
     577
     578The core {{ck}} macro has special support for
     579converting {{(quasiquote x)}} (also written as {{`x}})
     580into {{(c-quasiquote 'x)}}.
     581Within a call to {{c-quasiquote}}, you can use
     582{{(unquote y)}} (also written as {{,y}})
     583and {{(unquote-splicing z)}} (also written as {{,@z}}).
     584They are supported inside vectors as well as inside pairs/lists.
     585
     586<enscript highlight="scheme">
     587;; These expressions are exactly equivalent:
     588(ck () `(define (foo) (list ,@(c-list '1 '2) ,(c-vector '3))))
     589(ck () (c-quasiquote '(define (foo) (list ,@(c-list '1 '2) ,(c-vector '3)))))
     590;; ==> (define (foo) (list 1 2 #(3)))
     591
     592(ck () `#(1 ,@(c-list '2 '3)))
     593(ck () (c-quasiquote '#(1 ,@(c-list '2 '3))))
     594;; ==> #(1 2 3)
     595</enscript>
     596
     597
    363598<syntax>(c-eval '(OP ...))  →  result</syntax>
    364599
     
    387622
    388623Like {{c-call}}, but the last argument is a list of more arguments.
     624'''Prior to version 0.2.0''', the arguments in the final list required an extra level of quoting.
    389625Analogous to {{apply}}.
    390626
     
    393629;; ==> '(a (b) c d)
    394630</enscript>
    395 
    396 '''Prior to version 0.2.0''', the arguments in the final list required an extra level of quoting.
    397631
    398632
     
    429663
    430664
     665<syntax>(c-flip '(OP ...) X Y)  →  (OP ... Y X)</syntax>
     666
     667Calls the operation with the two extra arguments in reverse order.
     668Added in '''version 0.3.0'''.
     669
     670
     671<syntax>(c-branch '((OP ...) ...) X ...)  →  '(result ...)</syntax>
     672
     673Yields a list of the results of calling each operation with the {{X}}s.
     674Added in '''version 0.3.0'''.
     675
     676<enscript highlight="scheme">
     677(ck () (c-quote
     678        (c-branch '((c-list)
     679                    (c-cons)
     680                    (c-* '10))
     681                  '3 '5)))
     682;; '((3 5)
     683;;   (3 . 5)
     684;;   150)
     685</enscript>
     686
     687
    431688<syntax>(c-identity X)  →  X</syntax>
    432689
     
    440697
    441698
     699<syntax>(c-constantly X Y ...)  →  X</syntax>
     700
     701Always yields {{X}}, regardless of the other arguments.
     702May be useful for some higher-order macros.
     703Added in '''version 0.3.0'''.
     704
     705
     706==== CK-macro builders
     707
     708<syntax>(c-make-rules '(L ...) '(P X) ...)  →  '(syntax-rules ...)</syntax>
     709
     710Build a CK-macro based on syntax-rules.
     711Added in '''version 0.3.0'''.
     712
     713Given a list of zero or more literal symbols,
     714and one or more pattern/expression lists,
     715yields a syntax-rules form for a CK-macro with the following behavior:
     716
     717* Given argument(s) that match any pattern {{P}}, yields the value of
     718  the associated expression {{X}}, which may use identifiers from {{P}}.
     719  Fails if no pattern matches.
     720
     721Each pattern {{P}} is a list of zero or more sub-patterns,
     722which will be matched (as with syntax-rules)
     723against the already-evaluated and quoted arguments given to the new CK-macro.
     724Alternatively, {{P}} may be an identifier which will capture all arguments as a list.
     725
     726Each expression {{X}} is a single CK-macro expression or quoted value.
     727Identifiers from the pattern can be used in the expression, as with syntax-rules.
     728
     729Symbols in the literals list {{(L ...)}}
     730will be treated as literal identifiers in patterns.
     731Additionally, {{quote}} is always treated as a literal identifier.
     732
     733Caveats:
     734
     735* Using {{...}} in a pattern or expression may not work portably
     736  with all Scheme systems.
     737
     738* Symbols begining with {{%ck:}} are reserved for internal use and
     739  must not appear in any {{L}}, {{P}}, or {{X}}.
     740
     741<enscript highlight="scheme">
     742(ck () `(define-syntax c-flip-flop
     743          ,(c-make-rules '(flip flop)
     744            '(('flip 'x 'y)
     745              (c-list 'y 'x))
     746            '(('flop 'x 'y)
     747              '#f))))
     748
     749;; The above is basically equivalent to:
     750;; (define-syntax c-flip-flop
     751;;   (syntax-rules (flip flop quote)
     752;;     ((_ s 'flip 'x 'y)
     753;;      (ck s (c-list 'y 'x)))
     754;;     ((_ s 'flop 'x 'y)
     755;;      (ck s '#f))))
     756
     757(ck () (c-quote (c-flip-flop 'flip '1 '2)))
     758;; ==> '(1 2)
     759
     760(ck () (c-quote (c-flip-flop 'flop '1 '2)))
     761;; ==> #f
     762</enscript>
     763
     764
     765<syntax>(c-make-next '(X1 X2 ...))  →  '(syntax-rules ...)</syntax>
     766
     767Build a CK-macro that yields the next item in a sequence.
     768Added in '''version 0.3.0'''.
     769
     770Given a list of unique items, yields a syntax-rules form for a CK-macro
     771with the following behavior:
     772
     773* Given an item in the list, yields the item following it.
     774  Yields {{'#f}} if given the final item or an item not in the list.
     775
     776E.g. with a list of increasing integers, the CK-macro behaves like {{c-dadd1}}.
     777With a list of decreasing integers, it behaves like {{c-dsub1}}.
     778
     779The list must have at least two items, with no duplicates.
     780The items should be literal constants: booleans, numbers, strings, characters;
     781or (possibly nested) pairs, lists, or vectors of those things.
     782Symbols are allowed but the result may not be what you expect
     783because they are treated as identifiers in the patterns.
     784
     785Be advised that compilation can be very slow if there are many items
     786because it generates a syntax-rules with many branches.
     787
     788<enscript highlight="scheme">
     789(ck () `(define-syntax c-next-square
     790          ,(c-make-next '(0 1 4 9 16))))
     791
     792;; The above is basically equivalent to:
     793;; (define-syntax c-next-square
     794;;  (syntax-rules (quote)
     795;;    ((_ s '0) (ck s '1))
     796;;    ((_ s '1) (ck s '4))
     797;;    ((_ s '4) (ck s '9))
     798;;    ((_ s '9) (ck s '16))
     799;;    ((_ s otherwise) (ck s '#f))))
     800
     801(ck () (c-next-square '4))
     802;; ==> '9
     803(ck () (c-next-square '16))
     804;; ==> '#f
     805</enscript>
     806
     807
    442808==== Boolean Logic
    443809
     
    452818Always yields {{'#t}}, regardless of its arguments.
    453819May be useful for some higher-order macros.
     820Equivalent to {{(c-constantly '#t X ...)}}.
    454821Added in '''version 0.2.0'''.
    455822
     
    466833Always yields {{'#f}}, regardless of its arguments.
    467834May be useful for some higher-order macros.
     835Equivalent to {{(c-constantly '#f X ...)}}.
    468836Added in '''version 0.2.0'''.
    469837
     
    597965'''ATTENTION:''' This CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]]
    598966that you should be aware of.
    599 If you don't require strict R5RS portability, it is recommended to use {{c-eq?}} instead.
     967If you do not require strict R5RS portability, it is recommended to use {{c-eq?}} instead.
    600968
    601969Yields {{'#t}} if {{X}} and {{Y}} are the same symbol, otherwise yields {{'#f}}.
     
    614982'''ATTENTION:''' This CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]]
    615983that you should be aware of.
    616 If you don't require strict R5RS portability,
     984If you do not require strict R5RS portability,
    617985it is recommended to use {{c-equal?}} instead.
    618986
     
    6401008Yields {{'#f}} if {{X}} and {{Y}} have dissimilar structures (length, nesting, type),
    6411009or if {{OP}} yields {{'#f}} for any corresponding atoms of {{X}} and {{Y}}.
    642 Otherwise yields '#t.
     1010Otherwise yields {{'#t}}.
    6431011
    6441012<enscript highlight="scheme">
     
    6711039<enscript highlight="scheme">
    6721040(ck () (c-quote (c-cons 'a 'b)))
    673 ;; ==> '(a . b).
     1041;; ==> '(a . b)
    6741042
    6751043(ck () (c-quote (c-cons '+ '(1 2))))
    676 ;; ==> '(+ 1 2).
     1044;; ==> '(+ 1 2)
    6771045
    6781046(ck () (c-quote (c-cons '+ (c-cons '1 (c-cons '2 '())))))
    679 ;; ==> '(+ 1 2).
     1047;; ==> '(+ 1 2)
     1048</enscript>
     1049
     1050
     1051<syntax>(c-cons* X ... Y Z)  →  '(X ... Y . Z)</syntax>
     1052
     1053Yields a list from consing all the arguments together in a chain.
     1054If the final argument Z is a list, the result will be a proper list.
     1055Otherwise it will be a "dotted list".
     1056Analogous to {{cons*}} from SRFI 1.
     1057Added in '''version 0.3.0'''.
     1058
     1059<enscript highlight="scheme">
     1060(ck () (c-quote (c-cons* 'a 'b 'c 'd)))
     1061;; ==> '(a b c . d)
     1062(ck () (c-quote (c-cons* 'a 'b 'c '(d))))
     1063;; ==> '(a b c d)
    6801064</enscript>
    6811065
     
    6851069Like {{c-cons}}, but exchanges the order of arguments.
    6861070Analogous to {{xcons}} from SRFI 1.
     1071Added in '''version 0.2.0'''.
    6871072
    6881073<enscript highlight="scheme">
    6891074(ck () (c-quote (c-xcons 'a 'b)))
    690 ;; ==> '(b . a).
     1075;; ==> '(b . a)
    6911076</enscript>
    6921077
     
    8381223
    8391224
     1225<syntax>(c-prefix L X ...)  →  list</syntax>
     1226
     1227Yields the given list with the extra arguments added to the front.
     1228Added in '''version 0.3.0'''.
     1229
     1230<enscript highlight="scheme">
     1231(ck () (c-quote (c-prefix '(c d) 'a 'b)))
     1232;; ==> '(a b c d)
     1233</enscript>
     1234
     1235
    8401236<syntax>(c-suffix L X ...)  →  list</syntax>
    8411237
     
    8431239
    8441240<enscript highlight="scheme">
    845 (ck () (c-quote (c-suffix '(a) 'b 'c)))
    846 ;; ==> '(a b c)
     1241(ck () (c-quote (c-suffix '(a b) 'c 'd)))
     1242;; ==> '(a b c d)
    8471243</enscript>
    8481244
     
    8701266then appending the results.
    8711267The operation must be a CK-macro that yields a list.
    872 The operation may have leading arguments.
    8731268
    8741269Analogous to {{append-map}} from SFRI-1, but only accepts one list.
     
    8851280
    8861281Yields a list by calling the quoted operation on each item in the given list.
    887 The operation may have leading arguments.
    8881282Analogous to {{map}}, but only accepts one list.
    8891283(See also {{c-map2}} ... {{c-map5}} for versions that accept more lists.)
     
    9021296
    9031297Like {{c-map1}}, but they accept exactly two, three, four, or five lists respectively.
    904 {{OP}} must accept the two, three, four, or five extra arguments.
     1298{{OP}} must accept two, three, four, or five extra arguments.
    9051299If the lists are different lengths, terminates when the shortest list runs out.
    9061300Analogous to {{map}} from SRFI 1, but they accept a specific number of lists.
     
    9171311
    9181312Yield a value by repeatedly calling the quoted operation
    919 with each item from the list plus the previous result.
     1313with each item from the list and the previous result.
    9201314
    9211315If the list is empty, yields {{INIT}}.
    9221316Otherwise, the operation is first called with two arguments:
    923 the first item of the list, and INIT.
     1317the first item of the list, and {{INIT}}.
    9241318Then, the operation is repeatedly called with the next item of the list and the previous result,
    9251319until it reaches the end of the list.
     
    9371331
    9381332
     1333<syntax>(c-unfold '(P ...) '(F ...) '(G ...) SEED)  →  list</syntax>
     1334<syntax>(c-unfold '(P ...) '(F ...) '(G ...) SEED '(TAIL-GEN ...))  →  list</syntax>
     1335
     1336Generate a list by recursively "unfolding" from a seed.
     1337Analogous to {{unfold}} from SRFI 1.
     1338Added in '''version 0.3.0'''.
     1339
     1340Takes several operations which are called with the seed:
     1341
     1342* {{(P ... SEED)}} should yield non-{{'#f}} if it is time to stop generating.
     1343* {{(F ... SEED)}} should yield an item to be appended to the list.
     1344* {{(G ... SEED)}} should yield the next {{SEED}}.
     1345* {{(TAIL-GEN ... SEED)}} should yield the tail of the list.
     1346  Called with the final {{SEED}} after {{P}} yields non-{{'#f}}.
     1347  If omitted, {{'(TAIL-GEN ...)}} defaults to {{'(c-constantly '())}}.
     1348
     1349<enscript highlight="scheme">
     1350(ck () (c-quote
     1351        (c-unfold '(c-> '1)                        ; P
     1352                  '(c-identity)                    ; F
     1353                  '(c-dsub1)                       ; G
     1354                  '10                              ; SEED
     1355                  '(c-constantly '(BLASTOFF!)))))  ; TAIL-GEN
     1356;; ==> '(10 9 8 7 6 5 4 3 2 1 BLASTOFF!)
     1357</enscript>
     1358
     1359
    9391360<syntax>(c-filter '(OP ...) L)  →  list</syntax>
    9401361
    941 Yields a list by calling the quoted operation on each item in the given list,
     1362Yields a list by calling the predicate operation on each item in the list,
    9421363and discarding any item for which the test yields {{'#f}}.
    9431364Analogous to {{filter}} from SRFI 1.
     
    10001421'''ATTENTION:''' When using the default comparison operator,
    10011422this CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]] that you should be aware of.
    1002 If you don't require strict R5RS portability,
     1423If you do not require strict R5RS portability,
    10031424it is recommended to use the comparison operator {{'(c-equal?)}} instead.
    10041425
     
    10841505'''ATTENTION:''' When using the default comparison operator,
    10851506this CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]] that you should be aware of.
    1086 If you don't require strict R5RS portability,
     1507If you do not require strict R5RS portability,
    10871508it is recommended to use the comparison operator {{'(c-equal?)}} instead.
    10881509
     
    11121533'''ATTENTION:''' When using the default comparison operator,
    11131534this CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]] that you should be aware of.
    1114 If you don't require strict R5RS portability,
     1535If you do not require strict R5RS portability,
    11151536it is recommended to use the comparison operator {{'(c-equal?)}} instead.
    11161537
     
    11591580
    11601581
     1582<syntax>(c-vector-prefix V X ...)  →  list</syntax>
     1583
     1584Yields the given vector with the extra arguments added to the front.
     1585Added in '''version 0.3.0'''.
     1586
     1587<enscript highlight="scheme">
     1588(ck () (c-quote (c-vector-prefix '#(c d) 'a 'b)))
     1589;; ==> '#(a b c d)
     1590</enscript>
     1591
     1592
    11611593<syntax>(c-vector-suffix V X ...)  →  vector</syntax>
    11621594
     
    11871619
    11881620Yields a vector by calling the quoted operation on each item in the given vector.
    1189 The operation may have leading arguments.
    1190 
    11911621Analogous to {{vector-map}} from SRFI 43, but only accepts one vector.
    11921622'''Prior to version 0.2.0''', this was named {{c-vector-map}}.
     
    13651795
    13661796Based on {{c-mul}} from the original implementation,
    1367 except the symbol 'u has no special significance,
     1797except the symbol {{'u}} has no special significance,
    13681798and result is made from duplicating the first list.
    13691799
     
    13741804
    13751805
    1376 <syntax>(c-u/ U1 U2)  →  list</syntax>
     1806<syntax>(c-u/ U1 U2)  →  (list list)</syntax>
    13771807
    13781808Unary division.
     
    14171847Analogous to {{drop}} from SRFI 1,
    14181848but uses unary numbers,
    1419 and yields empty list if the list is too short.
     1849and yields the empty list if the list is too short.
    14201850
    14211851<enscript highlight="scheme">
     
    14441874
    14451875
     1876==== Decimal Integers
     1877
     1878<syntax>(c-dadd1 N)  →  'N+1 or '#f</syntax>
     1879
     1880Add 1 to a decimal integer.
     1881If 0 <= N <= 15, yields N + 1. Otherwise yields {{'#f}}.
     1882Added in '''version 0.3.0'''.
     1883
     1884<enscript highlight="scheme">
     1885(ck () (c-dadd1 '0))
     1886;; ==> '1
     1887(ck () (c-dadd1 '15))
     1888;; ==> '16
     1889(ck () (c-dadd1 '16))
     1890;; ==> '#f
     1891</enscript>
     1892
     1893The default domain is small because library compilation time increases rapidly
     1894the larger the domain is, because it generates a syntax-rules with many branches.
     1895You can define an {{add1}} with a larger (or just different) domain
     1896using {{c-make-next}} and a list of ''increasing'' integers:
     1897
     1898<enscript highlight="scheme">
     1899(ck () `(define-syntax c-my-add1
     1900          ,(c-make-next '(-5 -4 -3 -2 -1 0 1 2 3 4 5))))
     1901</enscript>
     1902
     1903
     1904<syntax>(c-dsub1 N)  →  'N-1 or '#f</syntax>
     1905
     1906Subtract 1 from a decimal integer.
     1907If 1 <= N <= 16, yields N - 1. Otherwise yields {{'#f}}.
     1908See the notes for {{c-dadd1}}.
     1909
     1910<enscript highlight="scheme">
     1911(ck () (c-dsub1 '16))
     1912;; ==> '15
     1913(ck () (c-dsub1 '1))
     1914;; ==> '0
     1915(ck () (c-dsub1 '0))
     1916;; ==> '#f
     1917</enscript>
     1918
     1919As with {{c-dadd1}}, you can define a {{sub1}} with a larger (or just different) domain
     1920using {{c-make-next}} and a list of ''decreasing'' integers:
     1921
     1922<enscript highlight="scheme">
     1923(ck () `(define-syntax c-my-sub1
     1924          ,(c-make-next '(5 4 3 2 1 0 -1 -2 -3 -4 -5))))
     1925</enscript>
     1926
     1927
     1928<syntax>(c-du N)  →  list or '#f</syntax>
     1929<syntax>(c-du N '(SUB1 ...))  →  list or '#f</syntax>
     1930
     1931Convert from decimal integers to [[#unary-math|unary integers]].
     1932If N is in the domain of {{SUB1}}, yields a list of that many elements,
     1933specifically the integers {{(N-1, ..., 0)}}.
     1934Otherwise, yields {{'#f}}.
     1935
     1936{{SUB1}} is any operation that given N yields N-1, where 1 <= N.
     1937Defaults to {{c-dsub1}}, which supports 1 <= N <= 16.
     1938See the note for {{c-dsub1}} for how to make an operation with a larger domain.
     1939
     1940<enscript highlight="scheme">
     1941(ck () (c-quote (c-du '0)))
     1942;; ==> '()
     1943(ck () (c-quote (c-du '16)))
     1944;; ==> '(15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0)
     1945(ck () (c-quote (c-du '17)))
     1946;; ==> '#f
     1947</enscript>
     1948
     1949
     1950<syntax>(c-ud U)  →  integer or '#f</syntax>
     1951<syntax>(c-ud U '(ADD1 ...))  →  integer or '#f</syntax>
     1952
     1953Convert from [[#unary-math|unary integers]] to decimal integers.
     1954Given a list of items, yields the list's length as a decimal integer.
     1955The contents of the list do not matter, only its length.
     1956If the list length is too large for {{ADD1}}, yields {{'#f}}.
     1957
     1958{{ADD1}} is any operation that given N yields N+1, where 0 <= N.
     1959Defaults to {{c-dadd1}}, which supports 0 <= N <= 15.
     1960See the note for {{c-dadd1}} for how to make an operation with a larger domain.
     1961
     1962<enscript highlight="scheme">
     1963(ck () (c-ud '()))
     1964;; ==> '0
     1965(ck () (c-ud '(a b c d e f g h i j k l m n o p)))
     1966;; ==> '16
     1967(ck () (c-ud '(a b c d e f g h i j k l m n o p q)))
     1968;; ==> '#f
     1969</enscript>
     1970
     1971
    14461972
    14471973=== Non-portable R5RS Wrappers
Note: See TracChangeset for help on using the changeset viewer.