1 | == ck-macros |
---|
2 | |
---|
3 | Composable Scheme macros based on the CK abstract machine. |
---|
4 | |
---|
5 | This 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]]" |
---|
7 | by Oleg Kiselyov. |
---|
8 | This egg provides the core {{ck}} macro, |
---|
9 | many useful (and some not-so-useful) predefined CK-macros, |
---|
10 | the {{ck-wrapper}} procedure, and many wrappers of R5RS procedures. |
---|
11 | |
---|
12 | If you create a useful or interesting general-purpose CK-macro, |
---|
13 | or an improvement to an existing CK-macro, |
---|
14 | please contact the maintainer (John) so your contribution can be added to the egg. |
---|
15 | All source code (including contributions) is public domain. |
---|
16 | |
---|
17 | ; Project / Source Code Repository: [[https://gitlab.com/jcroisant/ck-macros]] |
---|
18 | ; Maintainer: [[/users/john-croisant|John Croisant]] |
---|
19 | ; Based on work by: Oleg Kiselyov |
---|
20 | ; License: Public Domain |
---|
21 | |
---|
22 | |
---|
23 | '''Table of Contents''' |
---|
24 | [[toc:]] |
---|
25 | |
---|
26 | |
---|
27 | === Version History |
---|
28 | |
---|
29 | ; 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. |
---|
30 | ; 0.1.1 (2016-02-07) : Fixed {{c-append}} and {{c-vector-append}} failing when given one argument. |
---|
31 | ; 0.1.0 (2016-02-06) : Initial release. Includes version 1.1 (April 2011) of the core {{ck}} macro. Includes many CK-macros. |
---|
32 | |
---|
33 | For more information about what changed in each version, |
---|
34 | see the [[https://gitlab.com/jcroisant/ck-macros/blob/master/CHANGELOG.md|CHANGELOG]]. |
---|
35 | |
---|
36 | |
---|
37 | === What are CK-macros? |
---|
38 | |
---|
39 | CK-macros are Scheme macros written to be compatible with with the core {{ck}} macro. |
---|
40 | |
---|
41 | The core {{ck}} macro is a {{syntax-rules}} macro which implements the CK abstract machine. |
---|
42 | The CK abstract machine is a theoretical model of computation, |
---|
43 | described in the paper "Control Operators, the SECD-Machine, and the Lambda-Calculus" |
---|
44 | by Matthias Felleisen and Daniel P. Friedman. |
---|
45 | But, you don't need to read or understand the paper in order to create or use CK-macros! |
---|
46 | |
---|
47 | Basically, a CK-macro leverages the core {{ck}} macro |
---|
48 | to recursively expand the CK-macros's arguments first, |
---|
49 | before the CK-macro itself is expanded. |
---|
50 | This gives you more control over the macro expansion process, |
---|
51 | allowing you to easily combine simple reusable macros to form more complex macros. |
---|
52 | |
---|
53 | This is very similar to the way Scheme allows you to easily combine simple resuable functions |
---|
54 | ({{map}}, {{fold}}, {{cons}}, etc.) to create more complex functions. |
---|
55 | In fact, many useful Scheme functions can be translated to CK-macros, |
---|
56 | allowing you to portably achieve the same effect at macro-expansion time. |
---|
57 | You can even implement "higher-ordered macros" which take a macro as an argument. |
---|
58 | See {{c-map1}} and {{c-compose}} for examples of higher-ordered macros. |
---|
59 | |
---|
60 | CK-macros are not as flexibile, powerful, or efficient as |
---|
61 | CHICKEN's [[/man/5/Module (chicken syntax)|explicit and implicit renaming macros]], |
---|
62 | but CK-macros are much more portable. |
---|
63 | |
---|
64 | * The [[#ck|core {{ck}} macro]] and everything in the |
---|
65 | [[#portable-ck-macros|Portable CK-Macros]] section |
---|
66 | are implemented using only standard R5RS features, such as {{syntax-rules}}. |
---|
67 | This means they will work on any implementation of R5RS or later. |
---|
68 | |
---|
69 | * The [[#ck-wrapper|{{ck-wrapper}} procedure]] and everything in the |
---|
70 | [[#non-portable-r5rs-wrappers|Non-portable R5RS Wrappers]] section |
---|
71 | are implemented using |
---|
72 | [[/man/5/Module (chicken syntax)#explicit-renaming-macros|{{er-macro-transformer}}]], |
---|
73 | which is not standard R5RS but is available in many Scheme implementations. |
---|
74 | |
---|
75 | |
---|
76 | === How to write CK-macros |
---|
77 | |
---|
78 | (Note: If you don't care about strict R5RS portability, |
---|
79 | the easiest way to create a CK-macro is with [[#ck-wrapper|{{ck-wrapper}}]].) |
---|
80 | |
---|
81 | Here is a basic template for portable CK-macros: |
---|
82 | |
---|
83 | <enscript highlight="scheme"> |
---|
84 | (define-syntax c-foo |
---|
85 | (syntax-rules (quote) |
---|
86 | ((c-foo s 'input1 'input2 ...) |
---|
87 | (ck s output)))) |
---|
88 | </enscript> |
---|
89 | |
---|
90 | A CK-macro is just a normal macro that expands to a call to the core {{ck}} macro. |
---|
91 | To be portable, CK-macros are usually written using {{syntax-rules}}. |
---|
92 | But, you can write CK-macros using other macro systems, |
---|
93 | such as CHICKEN's [[/manual/Macros|explicit and implicit renaming macros]], |
---|
94 | as long your macro eventually expands into a call to the core {{ck}} macro. |
---|
95 | |
---|
96 | By convention, the names of CK-macros usually start with "c-", |
---|
97 | to distinguish them from non-CK macros or procedures with similar names. |
---|
98 | But, this naming convention is not required. |
---|
99 | |
---|
100 | CK-macros treat quoting specially, so you should have {{quote}} in the list of literal identifiers (the first argument to {{syntax-rules}}). |
---|
101 | You can also have other literal identifiers if needed. |
---|
102 | |
---|
103 | Every CK-macro's first argument must be the stack, usually called {{s}}. |
---|
104 | The stack is used internally by the core {{ck}} macro while recursively expanding macro arguments. |
---|
105 | Your CK-macro should not touch the stack, only pass it through to the core {{ck}} macro. |
---|
106 | |
---|
107 | Each {{'input}} is an argument passed to your macro. |
---|
108 | Your macro can have any number of input arguments, and they can be named whatever you want. |
---|
109 | They can also be lists or patterns, allowing you to destructure the arguments, |
---|
110 | as is often done with {{syntax-rules}} macros. |
---|
111 | |
---|
112 | The core {{ck}} macro expands the input arguments ahead of time, |
---|
113 | so the arguments will always be quoted values by the time your macro is expanded. |
---|
114 | Usually CK-macros are defined with their input arguments quoted (as above), |
---|
115 | so that you can easily destructure the input to use in your macro. |
---|
116 | You may recall that {{'a}} is translated by the reader to {{(quote a)}}. |
---|
117 | So, the above example is exactly the same as: |
---|
118 | |
---|
119 | <enscript highlight="scheme"> |
---|
120 | (define-syntax c-foo |
---|
121 | (syntax-rules (quote) |
---|
122 | ((c-foo s (quote input1) (quote input2) ...) |
---|
123 | (ck s output)))) |
---|
124 | </enscript> |
---|
125 | |
---|
126 | When written in this way, it is easier to see that {{input1}} and {{input2}} |
---|
127 | are merely placeholders in the {{syntax-rules}} pattern. |
---|
128 | (This is also why you must tell {{syntax-rules}} that {{quote}} is a literal identifier. |
---|
129 | Otherwise, {{syntax-rules}} would treat {{quote}} as a placeholder, too.) |
---|
130 | |
---|
131 | Your macro should transform the {{input}}s in some way to produce the {{output}}, |
---|
132 | which is passed to the core {{ck}} macro. |
---|
133 | The {{output}} must be either: |
---|
134 | |
---|
135 | * A quoted value, such as {{'a}}, {{'(+ 1 2)}}, {{'"foo"}}, {{'42}}, or {{'#t}}. |
---|
136 | * Or, an unquoted call to a CK-macro '''without the s argument''', such as {{(c-cons '+ '(1 2))}}. |
---|
137 | Nested calls are allowed, such as {{(c-cons '+ (c-list '1 '2))}}. |
---|
138 | |
---|
139 | Quoting is how the core {{ck}} macro knows the difference between a value and a CK-macro call. |
---|
140 | Therefore, '''all values must be quoted''', |
---|
141 | even values which normally do not need to be quoted in Scheme code, |
---|
142 | such as strings, numbers, and booleans. |
---|
143 | |
---|
144 | Eventually, your CK-macro must expand into a call to the core {{ck}} macro |
---|
145 | with a quoted value. |
---|
146 | We say that the macro "yields" this quoted value. |
---|
147 | The quoted value is either used as an argument to another CK-macro, |
---|
148 | or if your CK-macro is the outer-most CK-macro call, |
---|
149 | then the core {{ck}} macro expands into the '''unquoted value'''. |
---|
150 | |
---|
151 | So, if your CK-macro yields the quoted value {{'(+ 1 2)}}, |
---|
152 | and it is the outer-most CK-macro (not an argument to another CK-macro), |
---|
153 | the core {{ck}} macro will expand to the unquoted expression {{(+ 1 2)}}, |
---|
154 | which would later be evaluated to the number 3. |
---|
155 | (If you want to yield a quoted form as the final result, |
---|
156 | use {{c-quote}} as the outer-most CK-macro.) |
---|
157 | |
---|
158 | See [[http://okmij.org/ftp/Scheme/macros.html#ck-macros|the original article]] |
---|
159 | or [[https://gitlab.com/jcroisant/ck-macros/blob/master/lib/portable.scm|the source code]] |
---|
160 | for many examples of CK-macros. |
---|
161 | |
---|
162 | |
---|
163 | === Combining CK and non-CK macros |
---|
164 | |
---|
165 | The arguments to a CK-macro must either be a quoted value or a call to a CK-macro |
---|
166 | (i.e. a macro that expands to a call to the core {{ck}} macro). |
---|
167 | Therefore, most non-CK macros and special forms cannot be used as arguments to a CK-macro. |
---|
168 | |
---|
169 | Some non-CK macros can be used in a way that expands into a user-provided expression. |
---|
170 | It is therefore possible for these non-CK macros to be used as arguments to CK-macros, |
---|
171 | as long as they eventually expand into a call to the core {{ck}} macro. |
---|
172 | |
---|
173 | It is possible to write a non-CK macro which invokes a CK-macro via the core {{ck}} macro. |
---|
174 | For example, if you are writing a macro for other people to use, |
---|
175 | you can create a convenience macro, like so: |
---|
176 | |
---|
177 | <enscript highlight="scheme"> |
---|
178 | (define-syntax foo |
---|
179 | (syntax-rules () |
---|
180 | ((foo arg1 arg2 arg3) |
---|
181 | (ck () (c-foo 'arg1 'arg2 'arg3))))) |
---|
182 | </enscript> |
---|
183 | |
---|
184 | Also, it is possible for a CK-macro to expand into a call to a non-CK macro |
---|
185 | as its final result, or as part of the body of its final result. |
---|
186 | For example: |
---|
187 | |
---|
188 | <enscript highlight="scheme"> |
---|
189 | (ck () (c-list 'when (c-list '< '1 '2) (c-list 'print '"Yay!"))) |
---|
190 | ;;; Expands to the expression (when (< 1 2) (print "Yay!")). |
---|
191 | </enscript> |
---|
192 | |
---|
193 | |
---|
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. |
---|
201 | As explained in the section [[#how-to-write-ck-macros|How to write CK-macros]], |
---|
202 | all values must be quoted, |
---|
203 | even values which normally do not need to be quoted in Scheme code, |
---|
204 | such as strings, numbers, and booleans. |
---|
205 | |
---|
206 | For example, the code {{(ck () (c-not #t))}} will result in an error like this: |
---|
207 | |
---|
208 | Syntax error: no rule matches form |
---|
209 | |
---|
210 | (ck38782 (((c-not))) #t) |
---|
211 | |
---|
212 | The solution is to quote the {{#t}}, like this: {{(ck () (c-not '#t))}} |
---|
213 | |
---|
214 | |
---|
215 | === Known issues and limitations |
---|
216 | |
---|
217 | ==== Slow compilation |
---|
218 | |
---|
219 | CK-macros are pretty slow to compile, |
---|
220 | because the computation is done at compile time, |
---|
221 | using ''very'' deeply recursive macro expansions. |
---|
222 | |
---|
223 | Non-portable wrappers created with [[#ck-wrapper|{{ck-wrapper}}]] |
---|
224 | are probably somewhat faster than the portable CK-macros created with {{syntax-rules}}. |
---|
225 | But this library prioritizes portability over efficiency, |
---|
226 | so CK-macros are only implemented as wrappers if it is ''impossible'' |
---|
227 | to implement them using {{syntax-rules}}. |
---|
228 | |
---|
229 | You could likely improve compilation speed in your own code by |
---|
230 | redefining various CK-macros using {{ck-wrapper}}. |
---|
231 | |
---|
232 | |
---|
233 | ==== Pitfalls of c-sym-eq? |
---|
234 | |
---|
235 | {{c-sym-eq?}} has some strange and unexpected behaviors |
---|
236 | because of the way it uses {{let-syntax}}. |
---|
237 | |
---|
238 | * The behavior of {{c-sym-eq?}} is undefined and non-portable |
---|
239 | when comparing anything except symbols. |
---|
240 | |
---|
241 | * You should not use {{c-sym-eq?}} in any code that expands |
---|
242 | into a definition (of a variable, procedure, etc.), |
---|
243 | because that definition will not be visible from outside. |
---|
244 | This is because definitions that occur within the body of {{let-syntax}} |
---|
245 | are internal definitions, not global definitions. |
---|
246 | |
---|
247 | For example, this code will not work as expected: |
---|
248 | |
---|
249 | (ck () (c-list 'define 'x (c-sym-eq? 'a 'a))) |
---|
250 | |
---|
251 | You might expect it to expand to {{(define x #t)}}, |
---|
252 | defining a global variable {{x}} with the value {{#t}}. |
---|
253 | But even though {{c-sym-eq?}} seems to be used "inside" the definition, |
---|
254 | the core {{ck}} macro turns things "inside out" |
---|
255 | to eagerly expand macro arguments first. |
---|
256 | So, the definition will actually appear inside of a {{let-syntax}}, |
---|
257 | and {{x}} will not be visible from outside. |
---|
258 | |
---|
259 | These pitfalls also affect other macros that use {{c-sym-eq?}} directly or indirectly: |
---|
260 | |
---|
261 | * {{c-sym-equal?}} |
---|
262 | * {{c-member}} with the default comparison operator |
---|
263 | * {{c-assoc}} with the default comparison operator |
---|
264 | * {{c-alist-delete}} with the default comparison operator |
---|
265 | |
---|
266 | It is believed to be impossible to fix {{c-sym-eq?}} in a portable way, |
---|
267 | so it is recommended that you avoid using it or {{c-sym-equal?}} if possible. |
---|
268 | If you don't care about strict R5RS portability, |
---|
269 | you should use the non-portable wrappers {{c-eq?}} and {{c-equal?}} instead. |
---|
270 | |
---|
271 | |
---|
272 | === ck |
---|
273 | |
---|
274 | <syntax>(ck s 'v)</syntax> |
---|
275 | <syntax>(ck s (op ...))</syntax> |
---|
276 | |
---|
277 | This 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. |
---|
280 | |
---|
281 | ; 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))}}. |
---|
284 | Nested calls are allowed, such as {{(c-cons '+ (c-list '1 '2))}}. |
---|
285 | |
---|
286 | |
---|
287 | === ck-wrapper |
---|
288 | |
---|
289 | <procedure>(ck-wrapper proc) â macro transformer</procedure> |
---|
290 | |
---|
291 | Wrap a procedure in a CK-macro, returning a macro transformer |
---|
292 | that can be used with {{define-syntax}} or {{let-syntax}}. |
---|
293 | |
---|
294 | {{ck-wrapper}} requires '''version 0.2.0 or later''' of the ck-macros egg. |
---|
295 | It is considered '''non-portable''' because it depends on |
---|
296 | [[/man/5/Module (chicken syntax)#explicit-renaming-macros|{{er-macro-transformer}}]], |
---|
297 | which is not defined in standard R5RS. |
---|
298 | However, it should work on any Scheme which defines |
---|
299 | {{er-macro-transformer}} in the usual way. |
---|
300 | |
---|
301 | You can wrap any other expression that evaluates to a procedure, |
---|
302 | such as a procedure name, a lambda form, a "let over lambda" expression, etc. |
---|
303 | The expression will be evaluated once, |
---|
304 | when the call to {{ck-wrapper}} is evaluated. |
---|
305 | Therefore, the procedure you are wrapping must be available |
---|
306 | in the syntax environment at macro expansion time. |
---|
307 | (In other words, you should use |
---|
308 | [[/man/5/Module (chicken syntax)#define-for-syntax|{{define-for-syntax}}]], |
---|
309 | [[/man/5/Modules#import-for-syntax|{{import-for-syntax}}]], etc.) |
---|
310 | |
---|
311 | Examples: |
---|
312 | |
---|
313 | <enscript highlight="scheme"> |
---|
314 | ;;; Import iota from SRFI 1. |
---|
315 | (cond-expand |
---|
316 | (chicken-4 |
---|
317 | (use-for-syntax (only srfi-1 iota))) |
---|
318 | (chicken-5 |
---|
319 | (import-for-syntax (only (srfi 1) iota)))) |
---|
320 | |
---|
321 | (define-syntax c-iota (ck-wrapper iota)) |
---|
322 | |
---|
323 | (ck () (c-quote (c-iota '5))) |
---|
324 | ;; ==> '(0 1 2 3 4) |
---|
325 | |
---|
326 | ;;; A helper procedure that returns a closure. |
---|
327 | (define-for-syntax (make-adder n) |
---|
328 | (lambda (x) (+ x n))) |
---|
329 | |
---|
330 | ;;; Temporarily define a ck-wrapper around a closure. |
---|
331 | (let-syntax ((c-add2 (ck-wrapper (make-adder 2)))) |
---|
332 | ;; Map c-add2 over the result of c-iota. |
---|
333 | (ck () (c-quote (c-map1 '(c-add2) (c-iota '5))))) |
---|
334 | ;; ==> '(2 3 4 5 6) |
---|
335 | </enscript> |
---|
336 | |
---|
337 | |
---|
338 | === Portable CK-Macros |
---|
339 | |
---|
340 | The CK-macros in this section are defined using only standard R5RS features, |
---|
341 | such as {{syntax-rules}} and {{let-syntax}}. |
---|
342 | So, these CK-macros will work on any implementation of R5RS or later. |
---|
343 | |
---|
344 | |
---|
345 | ==== General |
---|
346 | |
---|
347 | <syntax>(c-quote X) â 'X</syntax> |
---|
348 | |
---|
349 | Adds an extra level of quotation to the argument. |
---|
350 | This is useful for macros that should expand to a quoted value. |
---|
351 | |
---|
352 | <enscript highlight="scheme"> |
---|
353 | ;; Without c-quote |
---|
354 | (ck () (c-cons '+ '(1 2))) |
---|
355 | ;; Expands to (+ 1 2), which evaluates to the number 3. |
---|
356 | |
---|
357 | ;; With c-quote |
---|
358 | (ck () (c-quote (c-cons '+ '(1 2)))) |
---|
359 | ;; Expands to '(+ 1 2), a quoted list. |
---|
360 | </enscript> |
---|
361 | |
---|
362 | |
---|
363 | <syntax>(c-eval '(OP ...)) â result</syntax> |
---|
364 | |
---|
365 | Takes a quoted operation and unquotes it, |
---|
366 | allowing the CK machine to expand it. |
---|
367 | Analogous to {{eval}}. |
---|
368 | |
---|
369 | <enscript highlight="scheme"> |
---|
370 | (ck () (c-quote (c-eval '(c-cons 'a 'b)))) |
---|
371 | ;; ==> '(a . b) |
---|
372 | </enscript> |
---|
373 | |
---|
374 | |
---|
375 | <syntax>(c-call '(OP ...) X ...) â result</syntax> |
---|
376 | |
---|
377 | Like {{c-eval}}, but adds the given arguments on to the end of the operation. |
---|
378 | Analogous to a lambda call in normal Scheme code. |
---|
379 | |
---|
380 | <enscript highlight="scheme"> |
---|
381 | (ck () (c-quote (c-call '(c-cons 'a) 'b))) |
---|
382 | ;; ==> '(a . b) |
---|
383 | </enscript> |
---|
384 | |
---|
385 | |
---|
386 | <syntax>(c-apply '(OP ...) X ... '(Y ...)) â result</syntax> |
---|
387 | |
---|
388 | Like {{c-call}}, but the last argument is a list of more arguments. |
---|
389 | Analogous to {{apply}}. |
---|
390 | |
---|
391 | <enscript highlight="scheme"> |
---|
392 | (ck () (c-quote (c-apply '(c-list) 'a '(b) '(c d)))) |
---|
393 | ;; ==> '(a (b) c d) |
---|
394 | </enscript> |
---|
395 | |
---|
396 | '''Prior to version 0.2.0''', the arguments in the final list required an extra level of quoting. |
---|
397 | |
---|
398 | |
---|
399 | <syntax>(c-compose '((OP-N ...) ... (OP-1 ...)) X ...) â result</syntax> |
---|
400 | |
---|
401 | Compose one or more CK-macros and apply them to the arguments. |
---|
402 | Calls the right-most {{OP}} with the arguments {{X ...}}, |
---|
403 | then calls the next-right-most {{OP}} with that result, and so on: |
---|
404 | |
---|
405 | (OP-N ... (OP-2 ... (OP-1 ... X ...))) |
---|
406 | |
---|
407 | {{OP-1}} must accept all the {{X}}s as arguments, |
---|
408 | and the other {{OP}}s must each accept one argument (the result of the previous operation). |
---|
409 | See also {{c-rcompose}}, which is more efficient. |
---|
410 | Added in '''version 0.2.0''' |
---|
411 | |
---|
412 | |
---|
413 | <enscript highlight="scheme"> |
---|
414 | (ck () (c-compose '((c-car) (c-cdr)) '(1 2 3))) |
---|
415 | ;; ==> 2 |
---|
416 | |
---|
417 | ;;; Map over a list of lists to see which are not empty. |
---|
418 | (ck () (c-quote (c-map1 '(c-compose '((c-not) (c-null?))) |
---|
419 | '((1) () (2 3))))) |
---|
420 | ;; ==> '(#t #f #t) |
---|
421 | </enscript> |
---|
422 | |
---|
423 | |
---|
424 | <syntax>(c-rcompose '((OP-1 ...) ... (OP-N ...)) X ...) â result</syntax> |
---|
425 | |
---|
426 | Like {{c-compose}}, but the operations are called in the reverse order (left to right). |
---|
427 | This is more efficient than {{c-compose}}. |
---|
428 | Added in '''version 0.2.0''' |
---|
429 | |
---|
430 | |
---|
431 | <syntax>(c-identity X) â X</syntax> |
---|
432 | |
---|
433 | Simply yields the value as given. |
---|
434 | Sometimes useful for higher-order macros like {{c-filter}}. |
---|
435 | |
---|
436 | <enscript highlight="scheme"> |
---|
437 | (ck () (c-quote (c-identity 'a))) |
---|
438 | ;; ==> 'a |
---|
439 | </enscript> |
---|
440 | |
---|
441 | |
---|
442 | ==== Boolean Logic |
---|
443 | |
---|
444 | <syntax>(c-not X) â '#t or '#f</syntax> |
---|
445 | |
---|
446 | Yields {{'#t}} if the argument is {{'#f}}, otherwise yields {{'#f}}. |
---|
447 | Analogous to {{not}}. |
---|
448 | |
---|
449 | |
---|
450 | <syntax>(c-true X ...) â '#t</syntax> |
---|
451 | |
---|
452 | Always yields {{'#t}}, regardless of its arguments. |
---|
453 | May be useful for some higher-order macros. |
---|
454 | Added in '''version 0.2.0'''. |
---|
455 | |
---|
456 | <enscript highlight="scheme"> |
---|
457 | ;;; Recursively check if two structure have the same length, |
---|
458 | ;;; nesting, etc, while ignoring the value of the atoms. |
---|
459 | (ck () (c-compare? '(c-true) '(1 #(2) 3) '(a #(b) c))) |
---|
460 | ;; ==> '#t |
---|
461 | </enscript> |
---|
462 | |
---|
463 | |
---|
464 | <syntax>(c-false X ...) â '#f</syntax> |
---|
465 | |
---|
466 | Always yields {{'#f}}, regardless of its arguments. |
---|
467 | May be useful for some higher-order macros. |
---|
468 | Added in '''version 0.2.0'''. |
---|
469 | |
---|
470 | |
---|
471 | <syntax>(c-if TEST PASS FAIL) â PASS or FAIL</syntax> |
---|
472 | |
---|
473 | Conditional branching. |
---|
474 | If {{TEST}} is {{'#f}}, this yields {{FAIL}}. |
---|
475 | Otherwise it yields {{PASS}}. |
---|
476 | |
---|
477 | Due to the way the CK machine works, both branches will be expanded, |
---|
478 | then the unneeded branch will be discarded. |
---|
479 | If you only want the needed branch to be expanded |
---|
480 | (e.g. because the branches are complex and slow to expand, |
---|
481 | or because it would be an error to expand the unneeded branch), |
---|
482 | use {{c-if*}} instead. |
---|
483 | |
---|
484 | Analogous to |
---|
485 | {{(lambda (test pass fail) (if test pass fail))}}. |
---|
486 | |
---|
487 | <enscript highlight="scheme"> |
---|
488 | (ck () (c-quote (c-if (c-pair? '(x)) |
---|
489 | 'pair |
---|
490 | 'not-pair))) |
---|
491 | ;; ==> 'pair |
---|
492 | |
---|
493 | (ck () (c-quote (c-if (c-pair? 'x) |
---|
494 | 'pair |
---|
495 | 'not-pair))) |
---|
496 | ;; ==> 'not-pair |
---|
497 | </enscript> |
---|
498 | |
---|
499 | |
---|
500 | <syntax>(c-if* TEST 'PASS 'FAIL) â PASS or FAIL</syntax> |
---|
501 | |
---|
502 | Similar to {{c-if}}, except that the branches must have an extra level of quoting, |
---|
503 | and only one branch will be expanded. |
---|
504 | This is more similar to how {{if}} behaves, but it is a bit awkward to use. |
---|
505 | |
---|
506 | Analogous to |
---|
507 | {{(lambda (test pass fail) (if test (eval pass) (eval fail)))}} |
---|
508 | |
---|
509 | <enscript highlight="scheme"> |
---|
510 | (ck () (c-quote (c-if* (c-pair? '(x)) |
---|
511 | '(c-car '(x)) |
---|
512 | ''not-pair)) |
---|
513 | ;; ==> 'x |
---|
514 | |
---|
515 | (ck () (c-quote (c-if* (c-pair? 'x) |
---|
516 | '(c-car 'x) |
---|
517 | ''not-pair)) |
---|
518 | ;; ==> 'not-pair |
---|
519 | </enscript> |
---|
520 | |
---|
521 | |
---|
522 | <syntax>(c-or X ...) â item or '#f</syntax> |
---|
523 | |
---|
524 | Yields the first argument that is not {{'#f}}. |
---|
525 | Yields {{'#f}} if all of the arguments are {{'#f}}, |
---|
526 | or if there are no arguments. |
---|
527 | |
---|
528 | Roughly analogous to {{or}}, except all arguments are expanded. |
---|
529 | If you only want to expand the arguments that are needed, use {{c-or*}} instead. |
---|
530 | |
---|
531 | |
---|
532 | <syntax>(c-or* 'X ...) â item or '#f</syntax> |
---|
533 | |
---|
534 | Similar to {{c-or}}, except that all the arguments must have an extra level of quoting, |
---|
535 | and the arguments will be expanded one at a time until a non-{{'#f}} value is found. |
---|
536 | This is more similar to how {{or}} behaves, but it is a bit awkward to use. |
---|
537 | |
---|
538 | |
---|
539 | <syntax>(c-and X ...) â item or '#f</syntax> |
---|
540 | |
---|
541 | If all arguments are not {{'#f}}, yields the last argument. |
---|
542 | If any of the arguments is {{'#f}}, yields {{'#f}}. |
---|
543 | If there are no arguments, yields {{'#t}}. |
---|
544 | |
---|
545 | Roughly analogous to {{and}}, except all arguments are expanded. |
---|
546 | If you only want to expand the arguments that are needed, use {{c-and*}} instead. |
---|
547 | |
---|
548 | |
---|
549 | <syntax>(c-and* X ...) â item or '#f</syntax> |
---|
550 | |
---|
551 | Similar to {{c-and}}, except that all the arguments must have an extra level of quoting, |
---|
552 | and the arguments will be expanded one at a time until a {{'#f}} value is found. |
---|
553 | This is more similar to how {{and}} behaves, but it is a bit awkward to use. |
---|
554 | |
---|
555 | |
---|
556 | <syntax>(c-null? X) â '#t or '#f</syntax> |
---|
557 | |
---|
558 | Yields {{'#t}} if {{X}} is the empty list, {{'()}}. |
---|
559 | Otherwise yields {{'#f}}. |
---|
560 | Analogous to {{null?}}. |
---|
561 | |
---|
562 | |
---|
563 | <syntax>(c-pair? X) â '#t or '#f</syntax> |
---|
564 | |
---|
565 | Yields {{'#t}} if {{X}} is a dotted pair or a non-empty list. |
---|
566 | Otherwise yields {{'#f}}. |
---|
567 | Analogous to {{pair?}}. |
---|
568 | |
---|
569 | |
---|
570 | <syntax>(c-not-pair? X) â '#t or '#f</syntax> |
---|
571 | |
---|
572 | Opposite of {{c-pair?}}. |
---|
573 | Analogous to {{not-pair?}} from SRFI 1. |
---|
574 | |
---|
575 | |
---|
576 | <syntax>(c-vector? X) â '#t or '#f</syntax> |
---|
577 | |
---|
578 | Yields {{'#t}} if {{X}} is a vector. |
---|
579 | Otherwise yields {{'#f}}. |
---|
580 | Analogous to {{vector?}}. |
---|
581 | |
---|
582 | <enscript highlight="scheme"> |
---|
583 | (ck () (c-quote (c-vector? '#(a)))) |
---|
584 | ;; ==> '#t |
---|
585 | </enscript> |
---|
586 | |
---|
587 | |
---|
588 | <syntax>(c-boolean? X) â '#t or '#f</syntax> |
---|
589 | |
---|
590 | Yields {{'#t}} if {{X}} is either {{'#t}} or {{'#f}}. |
---|
591 | Otherwise yields {{'#f}}. |
---|
592 | Analogous to {{boolean?}}. |
---|
593 | |
---|
594 | |
---|
595 | <syntax>(c-sym-eq? X Y) â '#t or '#f</syntax> |
---|
596 | |
---|
597 | '''ATTENTION:''' This CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]] |
---|
598 | that you should be aware of. |
---|
599 | If you don't require strict R5RS portability, it is recommended to use {{c-eq?}} instead. |
---|
600 | |
---|
601 | Yields {{'#t}} if {{X}} and {{Y}} are the same symbol, otherwise yields {{'#f}}. |
---|
602 | {{X}} should be a symbol. |
---|
603 | {{Y}} can be any value. |
---|
604 | Some Scheme implementations allow {{X}} to be other types, |
---|
605 | but this macro is only portable if {{X}} is a symbol. |
---|
606 | |
---|
607 | Roughly analogous to {{eq?}}, |
---|
608 | except it only works (portably) with symbols. |
---|
609 | Based on {{symbol-eq?}} from the original implementation. |
---|
610 | |
---|
611 | |
---|
612 | <syntax>(c-sym-equal? X Y) â '#t or '#f</syntax> |
---|
613 | |
---|
614 | '''ATTENTION:''' This CK-macro has [[#pitfalls-of-c-sym-eq|major pitfalls]] |
---|
615 | that you should be aware of. |
---|
616 | If you don't require strict R5RS portability, |
---|
617 | it is recommended to use {{c-equal?}} instead. |
---|
618 | |
---|
619 | Similar to {{c-sym-eq?}}, except it recursively compares |
---|
620 | pairs, lists, and vectors. |
---|
621 | |
---|
622 | Roughly analogous to {{equal?}}, |
---|
623 | except it only works (portably) with symbols, pairs, lists, vectors, |
---|
624 | and nested combinations of those things. |
---|
625 | |
---|
626 | |
---|
627 | <syntax>(c-compare? '(OP ...) X Y) â '#t or '#f</syntax> |
---|
628 | |
---|
629 | Recursively compares atoms, pairs, lists, or vectors, |
---|
630 | using {{OP}} as the predicate to compare atoms. |
---|
631 | Similar to {{equal?}} but with a custom predicate. |
---|
632 | Added in '''version 0.2.0'''. |
---|
633 | |
---|
634 | {{OP}} will be called with two arguments: |
---|
635 | an atom of {{X}}, and the corresponding atom of {{Y}}. |
---|
636 | In other words, the Nth atom of {{X}} will be compared with the Nth atom of {{Y}}, |
---|
637 | descending recursively into nested structures. |
---|
638 | If {{X}} and {{Y}} are themselves atoms, they are compared directly with {{OP}}. |
---|
639 | |
---|
640 | Yields {{'#f}} if {{X}} and {{Y}} have dissimilar structures (length, nesting, type), |
---|
641 | or if {{OP}} yields {{'#f}} for any corresponding atoms of {{X}} and {{Y}}. |
---|
642 | Otherwise yields '#t. |
---|
643 | |
---|
644 | <enscript highlight="scheme"> |
---|
645 | (ck () (c-compare? '(c-string-ci=?) '#("a" ("b")) '#("A" ("B")))) |
---|
646 | ;; ==> #t |
---|
647 | |
---|
648 | ;;; X is a vector with a list, but Y is a list with a vector. |
---|
649 | ;;; The structures are dissimilar. |
---|
650 | (ck () (c-compare? '(c-string-ci=?) '#("a" ("b")) '("a" #("b")))) |
---|
651 | ;; ==> #f |
---|
652 | |
---|
653 | ;;; Can use any predicate. Here, X and Y have same structure, |
---|
654 | ;;; and each atom of X is less than the correponding atom of Y. |
---|
655 | (ck () (c-compare? '(c-<) '(1 #(5)) '(2 #(6)))) |
---|
656 | ;; ==> #t |
---|
657 | |
---|
658 | ;;; Can compare atoms directly. |
---|
659 | (ck () (c-compare? '(c-<) '1 '2)) |
---|
660 | ;; ==> #t |
---|
661 | </enscript> |
---|
662 | |
---|
663 | |
---|
664 | ==== List Processing |
---|
665 | |
---|
666 | <syntax>(c-cons X Y) â '(X . Y)</syntax> |
---|
667 | |
---|
668 | Yields a pair with the two given arguments. |
---|
669 | Analogous to {{cons}}. |
---|
670 | |
---|
671 | <enscript highlight="scheme"> |
---|
672 | (ck () (c-quote (c-cons 'a 'b))) |
---|
673 | ;; ==> '(a . b). |
---|
674 | |
---|
675 | (ck () (c-quote (c-cons '+ '(1 2)))) |
---|
676 | ;; ==> '(+ 1 2). |
---|
677 | |
---|
678 | (ck () (c-quote (c-cons '+ (c-cons '1 (c-cons '2 '()))))) |
---|
679 | ;; ==> '(+ 1 2). |
---|
680 | </enscript> |
---|
681 | |
---|
682 | |
---|
683 | <syntax>(c-xcons X Y) â '(Y . X)</syntax> |
---|
684 | |
---|
685 | Like {{c-cons}}, but exchanges the order of arguments. |
---|
686 | Analogous to {{xcons}} from SRFI 1. |
---|
687 | |
---|
688 | <enscript highlight="scheme"> |
---|
689 | (ck () (c-quote (c-xcons 'a 'b))) |
---|
690 | ;; ==> '(b . a). |
---|
691 | </enscript> |
---|
692 | |
---|
693 | |
---|
694 | <syntax>(c-list X ...) â list</syntax> |
---|
695 | |
---|
696 | Yields a list containing the given items. |
---|
697 | Analogous to {{list}}. |
---|
698 | |
---|
699 | <enscript highlight="scheme"> |
---|
700 | (ck () (c-quote (c-list))) |
---|
701 | ;; ==> '() |
---|
702 | (ck () (c-quote (c-list 'a 'b 'c))) |
---|
703 | ;; ==> '(a b c) |
---|
704 | </enscript> |
---|
705 | |
---|
706 | |
---|
707 | <syntax>(c-car P) â item</syntax> |
---|
708 | |
---|
709 | Yields the head of the given pair. |
---|
710 | Analogous to {{car}}. |
---|
711 | |
---|
712 | <enscript highlight="scheme"> |
---|
713 | (ck () (c-quote (c-car '(a . b)))) |
---|
714 | ;; ==> 'a |
---|
715 | |
---|
716 | (ck () (c-quote (c-car '(a b)))) |
---|
717 | ;; ==> 'a |
---|
718 | </enscript> |
---|
719 | |
---|
720 | |
---|
721 | <syntax>(c-cdr P) â tail</syntax> |
---|
722 | |
---|
723 | Yields the tail of the given pair. |
---|
724 | Analogous to {{cdr}}. |
---|
725 | |
---|
726 | <enscript highlight="scheme"> |
---|
727 | (ck () (c-quote (c-cdr '(a . b)))) |
---|
728 | ;; ==> 'b |
---|
729 | |
---|
730 | (ck () (c-quote (c-cdr '(a b)))) |
---|
731 | ;; ==> '(b) |
---|
732 | </enscript> |
---|
733 | |
---|
734 | |
---|
735 | <syntax>(c-first L) â item</syntax> |
---|
736 | <syntax>(c-second L) â item</syntax> |
---|
737 | <syntax>(c-third L) â item</syntax> |
---|
738 | <syntax>(c-fourth L) â item</syntax> |
---|
739 | <syntax>(c-fifth L) â item</syntax> |
---|
740 | <syntax>(c-sixth L) â item</syntax> |
---|
741 | <syntax>(c-seventh L) â item</syntax> |
---|
742 | <syntax>(c-eighth L) â item</syntax> |
---|
743 | <syntax>(c-ninth L) â item</syntax> |
---|
744 | <syntax>(c-tenth L) â item</syntax> |
---|
745 | |
---|
746 | Yields the Nth item of the given list. |
---|
747 | Fails if the list is too short. |
---|
748 | |
---|
749 | Analogous to {{first}} ... {{tenth}} from SRFI 1. |
---|
750 | |
---|
751 | <enscript highlight="scheme"> |
---|
752 | (ck () (c-quote (c-first '(a b c d e f g h i j k)))) ; ==> 'a |
---|
753 | (ck () (c-quote (c-second '(a b c d e f g h i j k)))) ; ==> 'b |
---|
754 | (ck () (c-quote (c-third '(a b c d e f g h i j k)))) ; ==> 'c |
---|
755 | ;;; ... |
---|
756 | (ck () (c-quote (c-tenth '(a b c d e f g h i j k)))) ; ==> 'j |
---|
757 | </enscript> |
---|
758 | |
---|
759 | |
---|
760 | <syntax>(c-last L) â item</syntax> |
---|
761 | |
---|
762 | Yields the last value of the given list. |
---|
763 | Fails if the list is empty or is not a proper list. |
---|
764 | |
---|
765 | Analogous to {{last}} from SRFI 1. |
---|
766 | |
---|
767 | <enscript highlight="scheme"> |
---|
768 | (ck () (c-quote (c-last '(a b c)))) ; ==> 'c |
---|
769 | (ck () (c-quote (c-last '(a b . c)))) ; ==> ERROR! |
---|
770 | </enscript> |
---|
771 | |
---|
772 | |
---|
773 | <syntax>(c-last-pair L) â pair</syntax> |
---|
774 | |
---|
775 | Yields the last pair of the given list. |
---|
776 | Fails if the list is empty. |
---|
777 | |
---|
778 | Analogous to {{last-pair}} from SRFI 1. |
---|
779 | |
---|
780 | <enscript highlight="scheme"> |
---|
781 | (ck () (c-quote (c-last-pair '(a b c)))) ; ==> '(c) |
---|
782 | (ck () (c-quote (c-last-pair '(a b . c)))) ; ==> '(b . c) |
---|
783 | </enscript> |
---|
784 | |
---|
785 | |
---|
786 | <syntax>(c-drop1 L) â list</syntax> |
---|
787 | <syntax>(c-drop2 L) â list</syntax> |
---|
788 | <syntax>(c-drop3 L) â list</syntax> |
---|
789 | <syntax>(c-drop4 L) â list</syntax> |
---|
790 | <syntax>(c-drop5 L) â list</syntax> |
---|
791 | |
---|
792 | Drops a predefined number of items from the front of the given list. |
---|
793 | Fails if the list is too short. |
---|
794 | See also {{c-udrop}}. |
---|
795 | |
---|
796 | Analogous to {{(drop L N)}} from SRFI 1. |
---|
797 | |
---|
798 | <enscript highlight="scheme"> |
---|
799 | (ck () (c-quote (c-drop1 '(a b c d e f g)))) ; ==> '(b c d e f g) |
---|
800 | (ck () (c-quote (c-drop2 '(a b c d e f g)))) ; ==> '(c d e f g) |
---|
801 | (ck () (c-quote (c-drop3 '(a b c d e f g)))) ; ==> '(d e f g) |
---|
802 | (ck () (c-quote (c-drop4 '(a b c d e f g)))) ; ==> '(e f g) |
---|
803 | (ck () (c-quote (c-drop5 '(a b c d e f g)))) ; ==> '(f g) |
---|
804 | </enscript> |
---|
805 | |
---|
806 | |
---|
807 | <syntax>(c-take1 L) â list</syntax> |
---|
808 | <syntax>(c-take2 L) â list</syntax> |
---|
809 | <syntax>(c-take3 L) â list</syntax> |
---|
810 | <syntax>(c-take4 L) â list</syntax> |
---|
811 | <syntax>(c-take5 L) â list</syntax> |
---|
812 | |
---|
813 | Yields a list containing a predefined number of items from the front of the given list. |
---|
814 | Fails if the list is too short. |
---|
815 | See also {{c-utake}}. |
---|
816 | |
---|
817 | Analogous to {{(take L N)}} from SRFI 1. |
---|
818 | |
---|
819 | <enscript highlight="scheme"> |
---|
820 | (ck () (c-quote (c-take1 '(a b c d e f g)))) ; ==> '(a) |
---|
821 | (ck () (c-quote (c-take2 '(a b c d e f g)))) ; ==> '(a b) |
---|
822 | (ck () (c-quote (c-take3 '(a b c d e f g)))) ; ==> '(a b c) |
---|
823 | (ck () (c-quote (c-take4 '(a b c d e f g)))) ; ==> '(a b c d) |
---|
824 | (ck () (c-quote (c-take5 '(a b c d e f g)))) ; ==> '(a b c d e) |
---|
825 | </enscript> |
---|
826 | |
---|
827 | |
---|
828 | <syntax>(c-reverse L) â list</syntax> |
---|
829 | |
---|
830 | Yields the given list in reverse order. |
---|
831 | Fails if the list is not a proper list. |
---|
832 | Analogous to {{reverse}}. |
---|
833 | |
---|
834 | <enscript highlight="scheme"> |
---|
835 | (ck () (c-quote (c-reverse '(a b c)))) |
---|
836 | ;; ==> '(c b a) |
---|
837 | </enscript> |
---|
838 | |
---|
839 | |
---|
840 | <syntax>(c-suffix L X ...) â list</syntax> |
---|
841 | |
---|
842 | Yields the given list with the extra arguments added to the end. |
---|
843 | |
---|
844 | <enscript highlight="scheme"> |
---|
845 | (ck () (c-quote (c-suffix '(a) 'b 'c))) |
---|
846 | ;; ==> '(a b c) |
---|
847 | </enscript> |
---|
848 | |
---|
849 | |
---|
850 | <syntax>(c-append L ...) â list</syntax> |
---|
851 | |
---|
852 | Appends the given lists. |
---|
853 | Analogous to {{append}}. |
---|
854 | |
---|
855 | <enscript highlight="scheme"> |
---|
856 | (ck () (c-quote (c-append))) |
---|
857 | ;; ==> '() |
---|
858 | |
---|
859 | (ck () (c-quote (c-append '(+) (c-append '(1) '(2))))) |
---|
860 | ;; ==> '(+ 1 2) |
---|
861 | |
---|
862 | (ck () (c-quote (c-append '(define foo) '((+ 1 2))))) |
---|
863 | ;; ==> '(define foo (+ 1 2 3)) |
---|
864 | </enscript> |
---|
865 | |
---|
866 | |
---|
867 | <syntax>(c-append-map1 '(OP ...) L) â list</syntax> |
---|
868 | |
---|
869 | Yields a list by calling the quoted operation on each item in the list, |
---|
870 | then appending the results. |
---|
871 | The operation must be a CK-macro that yields a list. |
---|
872 | The operation may have leading arguments. |
---|
873 | |
---|
874 | Analogous to {{append-map}} from SFRI-1, but only accepts one list. |
---|
875 | '''Prior to version 0.2.0''', this was named {{c-append-map}}. |
---|
876 | This was named {{c-concatMap}} in the original implementation. |
---|
877 | |
---|
878 | <enscript highlight="scheme"> |
---|
879 | (ck () (c-quote (c-append-map1 '(c-list 'a 'b) '(1 2)))) |
---|
880 | ;; ==> '(a b 1 a b 2) |
---|
881 | </enscript> |
---|
882 | |
---|
883 | |
---|
884 | <syntax>(c-map1 '(OP ...) L) â list</syntax> |
---|
885 | |
---|
886 | Yields a list by calling the quoted operation on each item in the given list. |
---|
887 | The operation may have leading arguments. |
---|
888 | Analogous to {{map}}, but only accepts one list. |
---|
889 | (See also {{c-map2}} ... {{c-map5}} for versions that accept more lists.) |
---|
890 | '''Prior to version 0.2.0''', this was named {{c-map}}. |
---|
891 | |
---|
892 | <enscript highlight="scheme"> |
---|
893 | (ck () (c-quote (c-map1 '(c-cons 'a) '(1 2)))) |
---|
894 | ;; ==> '((a . 1) (a . 2)) |
---|
895 | </enscript> |
---|
896 | |
---|
897 | |
---|
898 | <syntax>(c-map2 '(OP ...) L1 L2) â list</syntax> |
---|
899 | <syntax>(c-map3 '(OP ...) L1 L2 L3) â list</syntax> |
---|
900 | <syntax>(c-map4 '(OP ...) L1 L2 L3 L4) â list</syntax> |
---|
901 | <syntax>(c-map5 '(OP ...) L1 L2 L3 L4 L5) â list</syntax> |
---|
902 | |
---|
903 | Like {{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. |
---|
905 | If the lists are different lengths, terminates when the shortest list runs out. |
---|
906 | Analogous to {{map}} from SRFI 1, but they accept a specific number of lists. |
---|
907 | Added in '''version 0.2.0'''. |
---|
908 | |
---|
909 | <enscript highlight="scheme"> |
---|
910 | ;; The argument '(1 2) is shortest so the result only has two items. |
---|
911 | (ck () (c-quote (c-map3 '(c-list) '(a b c) '(1 2) '(x y z)))) |
---|
912 | ;; ==> '((a 1 x) (b 2 y)) |
---|
913 | </enscript> |
---|
914 | |
---|
915 | |
---|
916 | <syntax>(c-fold1 '(OP ...) INIT L) â result</syntax> |
---|
917 | |
---|
918 | Yield a value by repeatedly calling the quoted operation |
---|
919 | with each item from the list plus the previous result. |
---|
920 | |
---|
921 | If the list is empty, yields {{INIT}}. |
---|
922 | Otherwise, the operation is first called with two arguments: |
---|
923 | the first item of the list, and INIT. |
---|
924 | Then, the operation is repeatedly called with the next item of the list and the previous result, |
---|
925 | until it reaches the end of the list. |
---|
926 | Yields the final result. |
---|
927 | |
---|
928 | Analogous to {{fold}} from SRFI 1, but only accepts one list. |
---|
929 | '''Prior to version 0.2.0''', this was named {{c-fold}}. |
---|
930 | |
---|
931 | <enscript highlight="scheme"> |
---|
932 | (ck () (c-quote (c-fold1 '(c-cons) '(x) '()))) |
---|
933 | ;; ==> '(x) |
---|
934 | (ck () (c-quote (c-fold1 '(c-cons) '(x) '(a b c d e f)))) |
---|
935 | ;; ==> '(f e d c b a x) |
---|
936 | </enscript> |
---|
937 | |
---|
938 | |
---|
939 | <syntax>(c-filter '(OP ...) L) â list</syntax> |
---|
940 | |
---|
941 | Yields a list by calling the quoted operation on each item in the given list, |
---|
942 | and discarding any item for which the test yields {{'#f}}. |
---|
943 | Analogous to {{filter}} from SRFI 1. |
---|
944 | |
---|
945 | <enscript highlight="scheme"> |
---|
946 | (ck () (c-quote (c-filter '(c-pair?) |
---|
947 | '(a (b . c) 1 (d e) #t)))) |
---|
948 | ;; ==> '((b . c) (d e)) |
---|
949 | </enscript> |
---|
950 | |
---|
951 | |
---|
952 | <syntax>(c-remove '(OP ...) L) â list</syntax> |
---|
953 | |
---|
954 | Opposite of {{c-filter}}. |
---|
955 | Discards items that pass the test, keeps items that fail the test. |
---|
956 | Analogous to {{remove}} from SRFI 1. |
---|
957 | |
---|
958 | <enscript highlight="scheme"> |
---|
959 | (ck () (c-quote (c-remove '(c-pair?) |
---|
960 | '(a (b . c) 1 (d e) #t)))) |
---|
961 | ;; ==> '(a 1 #t) |
---|
962 | </enscript> |
---|
963 | |
---|
964 | |
---|
965 | <syntax>(c-find '(OP ...) L) â item or '#f</syntax> |
---|
966 | |
---|
967 | Searches the list for the first item that passes the predicate operation |
---|
968 | (i.e. the predicate yields a non-{{'#f}} value), |
---|
969 | then yields that item. |
---|
970 | Yields {{'#f}} if no item passes the predicate. |
---|
971 | |
---|
972 | Analogous to {{find}} from SRFI 1. |
---|
973 | |
---|
974 | <enscript highlight="scheme"> |
---|
975 | (ck () (c-quote (c-find '(c-pair?) |
---|
976 | '(a (b . c) 1 (d e) #t)))) |
---|
977 | ;; ==> '(b . c) |
---|
978 | </enscript> |
---|
979 | |
---|
980 | |
---|
981 | <syntax>(c-find-tail '(OP ...) L) â pair or '#f</syntax> |
---|
982 | |
---|
983 | Searches the list for the first item that passes the predicate operation |
---|
984 | (i.e. the predicate yields a non-{{'#f}} value), |
---|
985 | then yields the tail of the list starting with that item. |
---|
986 | Yields {{'#f}} if no item passes the predicate. |
---|
987 | |
---|
988 | Analogous to {{find-tail}} from SRFI 1. |
---|
989 | |
---|
990 | <enscript highlight="scheme"> |
---|
991 | (ck () (c-quote (c-find-tail '(c-pair?) |
---|
992 | '(a (b . c) 1 (d e) #t)))) |
---|
993 | ;; ==> '((b . c) 1 (d e) #t) |
---|
994 | </enscript> |
---|
995 | |
---|
996 | |
---|
997 | <syntax>(c-member X L) â '#t or '#f</syntax> |
---|
998 | <syntax>(c-member X L '(OP ...)) â '#t or '#f</syntax> |
---|
999 | |
---|
1000 | '''ATTENTION:''' When using the default comparison operator, |
---|
1001 | this 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, |
---|
1003 | it is recommended to use the comparison operator {{'(c-equal?)}} instead. |
---|
1004 | |
---|
1005 | Searches the list for the first occurance of {{X}}, |
---|
1006 | then yields the tail of the list starting with that item. |
---|
1007 | Yields {{'#f}} if the list does not contain {{X}}. |
---|
1008 | |
---|
1009 | Uses {{'(OP ...)}} for comparison, |
---|
1010 | or {{'(c-sym-equal?)}} if the operation is omitted. |
---|
1011 | So by default, {{X}} must be a symbol, list, pair, vector, |
---|
1012 | or nested combination of those things. |
---|
1013 | |
---|
1014 | Same as {{(c-find-tail '(OP ... X) L)}}. |
---|
1015 | Roughly analogous to {{member}} except for the default allowed types. |
---|
1016 | |
---|
1017 | <enscript highlight="scheme"> |
---|
1018 | (ck () (c-quote (c-member 'b '(a b c)))) |
---|
1019 | ;; ==> '(b c) |
---|
1020 | |
---|
1021 | (ck () (c-quote (c-member 'x '(a b c)))) |
---|
1022 | ;; ==> '#f |
---|
1023 | |
---|
1024 | (ck () (c-quote (c-member '(a b c) |
---|
1025 | '((a) (x y z) (a b)) |
---|
1026 | '(c-u=)))) |
---|
1027 | ;; ==> '((x y z) (a b)) |
---|
1028 | ;; Because (c-u= '(a b c) '(x y z)) yields '#t |
---|
1029 | </enscript> |
---|
1030 | |
---|
1031 | |
---|
1032 | <syntax>(c-any1 '(OP ...) L) â result or '#f</syntax> |
---|
1033 | |
---|
1034 | Calls the operation on each value in the given list |
---|
1035 | until it finds a result that is not {{'#f}}, then yields that result. |
---|
1036 | Yields {{'#f}} if the predicate yields {{'#f}} for all items in the list, |
---|
1037 | or if the list is empty. |
---|
1038 | |
---|
1039 | Analogous to {{any}} from SRFI 1, but only accepts one list. |
---|
1040 | '''Prior to version 0.2.0''', this was named {{c-any}}. |
---|
1041 | |
---|
1042 | <enscript highlight="scheme"> |
---|
1043 | (ck () (c-quote (c-any1 '(c-pair?) '()))) |
---|
1044 | ;; ==> '#f |
---|
1045 | (ck () (c-quote (c-any1 '(c-pair?) '(a b c)))) |
---|
1046 | ;; ==> '#f |
---|
1047 | (ck () (c-quote (c-any1 '(c-pair?) '(a (b . c))))) |
---|
1048 | ;; ==> '#t |
---|
1049 | |
---|
1050 | (ck () (c-quote (c-any1 '(c-cons 'z) '(a b c)))) |
---|
1051 | ;; ==> '(1 . a) |
---|
1052 | ;; Because (c-cons 'z 'a) yields a value that is not '#f. |
---|
1053 | </enscript> |
---|
1054 | |
---|
1055 | |
---|
1056 | <syntax>(c-every1 '(OP ...) L) â result or '#f</syntax> |
---|
1057 | |
---|
1058 | Calls the operation on each value in the given list |
---|
1059 | until it finds a result that is {{'#f}}, then yields {{'#f}}. |
---|
1060 | If the predicate yields a non-{{'#f}} value for every item in the list, |
---|
1061 | this yields the result of calling the predicate on the last item. |
---|
1062 | Yields {{'#t}} if the list is empty. |
---|
1063 | |
---|
1064 | Analogous to {{every}} from SRFI 1, but only accepts one list. |
---|
1065 | '''Prior to version 0.2.0''', this was named {{c-every}}. |
---|
1066 | |
---|
1067 | <enscript highlight="scheme"> |
---|
1068 | (ck () (c-quote (c-every1 '(c-pair?) '()))) |
---|
1069 | ;; ==> '#t |
---|
1070 | (ck () (c-quote (c-every1 '(c-pair?) '(a (b . c))))) |
---|
1071 | ;; ==> '#f |
---|
1072 | (ck () (c-quote (c-every1 '(c-pair?) '((a . b) (b . c))))) |
---|
1073 | ;; ==> '#t |
---|
1074 | |
---|
1075 | (ck () (c-quote (c-every1 '(c-cons 'z) '(a b c)))) |
---|
1076 | ;; ==> '(z . c) |
---|
1077 | ;; Because all results were non-'#f and (c-cons 'z 'c) was the final operation. |
---|
1078 | </enscript> |
---|
1079 | |
---|
1080 | |
---|
1081 | <syntax>(c-assoc KEY ALIST) â pair or '#f</syntax> |
---|
1082 | <syntax>(c-assoc KEY ALIST '(OP ...)) â pair or '#f</syntax> |
---|
1083 | |
---|
1084 | '''ATTENTION:''' When using the default comparison operator, |
---|
1085 | this 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, |
---|
1087 | it is recommended to use the comparison operator {{'(c-equal?)}} instead. |
---|
1088 | |
---|
1089 | Searches {{ALIST}} for the first pair whose car matches {{KEY}}, |
---|
1090 | then yields that pair. |
---|
1091 | Yields {{'#f}} if no match is found. |
---|
1092 | {{ALIST}} must be an association list, i.e. a list of pairs. |
---|
1093 | |
---|
1094 | Uses {{'(OP ...)}} for comparison, |
---|
1095 | or {{'(c-sym-equal?)}} if {{'(OP ...)}} is omitted. |
---|
1096 | |
---|
1097 | Analogous to {{assoc}} from SRFI 1. |
---|
1098 | |
---|
1099 | <enscript highlight="scheme"> |
---|
1100 | (ck () (c-quote (c-assoc 'x '((a . 1) (b . 2) (a . 3))))) |
---|
1101 | ;; ==> '#f |
---|
1102 | (ck () (c-quote (c-assoc 'a '((a . 1) (b . 2) (a . 3))))) |
---|
1103 | ;; ==> '(a . 1) |
---|
1104 | (ck () (c-quote (c-assoc '(a) '((a . 1) (b . 2) ((a) . 3))))) |
---|
1105 | ;; ==> '((a) . 3) |
---|
1106 | </enscript> |
---|
1107 | |
---|
1108 | |
---|
1109 | <syntax>(c-alist-delete KEY ALIST) â list</syntax> |
---|
1110 | <syntax>(c-alist-delete KEY ALIST '(OP ...)) â list</syntax> |
---|
1111 | |
---|
1112 | '''ATTENTION:''' When using the default comparison operator, |
---|
1113 | this 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, |
---|
1115 | it is recommended to use the comparison operator {{'(c-equal?)}} instead. |
---|
1116 | |
---|
1117 | Removes all pairs in {{ALIST}} whose car matches {{KEY}}. |
---|
1118 | {{ALIST}} must be an association list, i.e. a list of pairs. |
---|
1119 | |
---|
1120 | Uses {{'(OP ...)}} for comparison, |
---|
1121 | or {{'(c-sym-equal?)}} if {{'(OP ...)}} is omitted. |
---|
1122 | |
---|
1123 | Analogous to {{alist-delete}} from SRFI 1. |
---|
1124 | Based on {{c-delete-assoc}} from the original implementation. |
---|
1125 | |
---|
1126 | <enscript highlight="scheme"> |
---|
1127 | (ck () (c-quote (c-alist-delete 'a '((a . 1) (b . 2) (a . 3) (c . 4))))) |
---|
1128 | ;; ==> '((b . 2) (c . 4) |
---|
1129 | (ck () (c-quote (c-alist-delete '(a) '((a . 1) (b . 2) ((a) . 3))))) |
---|
1130 | ;; ==> '((a . 1) (b . 2)) |
---|
1131 | </enscript> |
---|
1132 | |
---|
1133 | |
---|
1134 | ==== Vector Processing |
---|
1135 | |
---|
1136 | <syntax>(c-vector X ...) â vector</syntax> |
---|
1137 | |
---|
1138 | Yields a vector containing the given items. |
---|
1139 | Analogous to {{vector}}. |
---|
1140 | |
---|
1141 | |
---|
1142 | <syntax>(c-list->vector L) â vector</syntax> |
---|
1143 | |
---|
1144 | Yields a vector containing the same items as the given list. |
---|
1145 | Analogous to {{list->vector}} from SRFI 43. |
---|
1146 | |
---|
1147 | |
---|
1148 | <syntax>(c-vector->list V) â list</syntax> |
---|
1149 | |
---|
1150 | Yields a list containing the same items as the given vector. |
---|
1151 | Analogous to {{vector->list}} from SRFI 43. |
---|
1152 | |
---|
1153 | |
---|
1154 | <syntax>(c-vector-reverse V) â vector</syntax> |
---|
1155 | |
---|
1156 | Yields the given vector in reverse order. |
---|
1157 | Similar to {{vector-reverse-copy}} from SRFI 43, |
---|
1158 | but does not take a start or end argument. |
---|
1159 | |
---|
1160 | |
---|
1161 | <syntax>(c-vector-suffix V X ...) â vector</syntax> |
---|
1162 | |
---|
1163 | Yields the given vector with the extra arguments added to the end. |
---|
1164 | |
---|
1165 | <enscript highlight="scheme"> |
---|
1166 | (ck () (c-quote (c-vector-suffix '#(a b) 'c 'd))) |
---|
1167 | ;; ==> '#(a b c d) |
---|
1168 | </enscript> |
---|
1169 | |
---|
1170 | |
---|
1171 | <syntax>(c-vector-append V ...) â vector</syntax> |
---|
1172 | |
---|
1173 | Appends the given vectors. |
---|
1174 | Analogous to {{vector-append}} from SRFI 43, |
---|
1175 | but only accepts two vectors. |
---|
1176 | |
---|
1177 | <enscript highlight="scheme"> |
---|
1178 | (ck () (c-quote (c-vector-append))) |
---|
1179 | ;; ==> '#() |
---|
1180 | |
---|
1181 | (ck () (c-quote (c-vector-append '#(a b) '#(c d) '#(e f)))) |
---|
1182 | ;; ==> '#(a b c d e f) |
---|
1183 | </enscript> |
---|
1184 | |
---|
1185 | |
---|
1186 | <syntax>(c-vector-map1 '(OP ...) V) â vector</syntax> |
---|
1187 | |
---|
1188 | Yields a vector by calling the quoted operation on each item in the given vector. |
---|
1189 | The operation may have leading arguments. |
---|
1190 | |
---|
1191 | Analogous to {{vector-map}} from SRFI 43, but only accepts one vector. |
---|
1192 | '''Prior to version 0.2.0''', this was named {{c-vector-map}}. |
---|
1193 | |
---|
1194 | |
---|
1195 | ==== Unary Math |
---|
1196 | |
---|
1197 | The CK-macros in this section perform mathematical operations by treating lists as unary numbers. |
---|
1198 | Unary math is pretty slow for large values or complex operations, |
---|
1199 | but it is interesting, portable, and maybe even useful in some cases. |
---|
1200 | |
---|
1201 | Unary numbers are a way of representing non-negative integers as a list of a certain length. |
---|
1202 | For example, the list {{'(a b c d e)}} means the number 5, |
---|
1203 | and the list {{'()}} means the number 0. |
---|
1204 | The contents of the list do not matter, only the length. |
---|
1205 | Negative numbers and non-integral numbers cannot be represented in unary. |
---|
1206 | |
---|
1207 | |
---|
1208 | <syntax>(c-u= U1 U2) â '#t or '#f</syntax> |
---|
1209 | |
---|
1210 | Unary equality. |
---|
1211 | Yields {{'#t}} if the two lists have the same lengths, |
---|
1212 | otherwise yields {{'#f}}. |
---|
1213 | |
---|
1214 | <enscript highlight="scheme"> |
---|
1215 | (ck () (c-quote (c-u= '(a b c) '(a b c)))) |
---|
1216 | ;; ==> '#t |
---|
1217 | (ck () (c-quote (c-u= '(1 2 3) '(a b c)))) |
---|
1218 | ;; ==> '#t |
---|
1219 | (ck () (c-quote (c-u= '(1 2) '(a b c)))) |
---|
1220 | ;; ==> '#f |
---|
1221 | </enscript> |
---|
1222 | |
---|
1223 | |
---|
1224 | <syntax>(c-u< U1 U2) â '#t or '#f</syntax> |
---|
1225 | |
---|
1226 | Unary less-than. |
---|
1227 | Yields {{'#t}} if the first list is shorter than the second list, |
---|
1228 | otherwise yields {{'#f}}. |
---|
1229 | |
---|
1230 | <enscript highlight="scheme"> |
---|
1231 | (ck () (c-quote (c-u< '(1 2) '(a b c)))) |
---|
1232 | ;; ==> '#t |
---|
1233 | (ck () (c-quote (c-u< '(1 2 3) '(a b c)))) |
---|
1234 | ;; ==> '#f |
---|
1235 | </enscript> |
---|
1236 | |
---|
1237 | |
---|
1238 | <syntax>(c-u<= U1 U2) â '#t or '#f</syntax> |
---|
1239 | |
---|
1240 | Unary less-than-or-equals. |
---|
1241 | Yields {{'#t}} if first list is the same length or shorter than the second list, |
---|
1242 | otherwise yields {{'#f}}. |
---|
1243 | |
---|
1244 | <enscript highlight="scheme"> |
---|
1245 | (ck () (c-quote (c-u<= '(1 2) '(a b c)))) |
---|
1246 | ;; ==> '#t |
---|
1247 | (ck () (c-quote (c-u<= '(1 2 3) '(a b c)))) |
---|
1248 | ;; ==> '#t |
---|
1249 | (ck () (c-quote (c-u<= '(1 2 3 4) '(a b c)))) |
---|
1250 | ;; ==> '#f |
---|
1251 | </enscript> |
---|
1252 | |
---|
1253 | |
---|
1254 | <syntax>(c-u> U1 U2) â '#t or '#f</syntax> |
---|
1255 | |
---|
1256 | Unary greater-than. |
---|
1257 | Yields {{'#t}} if the first list is longer than the second list, |
---|
1258 | otherwise yields {{'#f}}. |
---|
1259 | |
---|
1260 | <enscript highlight="scheme"> |
---|
1261 | (ck () (c-quote (c-u> '(1 2 3 4) '(a b c)))) |
---|
1262 | ;; ==> '#t |
---|
1263 | (ck () (c-quote (c-u> '(1 2 3) '(a b c)))) |
---|
1264 | ;; ==> '#f |
---|
1265 | </enscript> |
---|
1266 | |
---|
1267 | |
---|
1268 | <syntax>(c-u>= U1 U2) â '#t or '#f</syntax> |
---|
1269 | |
---|
1270 | Unary greater-than-or-equals. |
---|
1271 | Yields {{'#t}} if first list is same length or longer than the second list, |
---|
1272 | otherwise yields {{'#f}}. |
---|
1273 | |
---|
1274 | <enscript highlight="scheme"> |
---|
1275 | (ck () (c-quote (c-u>= '(1 2 3 4) '(a b c)))) |
---|
1276 | ;; ==> '#t |
---|
1277 | (ck () (c-quote (c-u>= '(1 2 3) '(a b c)))) |
---|
1278 | ;; ==> '#t |
---|
1279 | (ck () (c-quote (c-u>= '(1 2) '(a b c)))) |
---|
1280 | ;; ==> '#f |
---|
1281 | </enscript> |
---|
1282 | |
---|
1283 | |
---|
1284 | <syntax>(c-uzero? U) â '#t or '#f</syntax> |
---|
1285 | |
---|
1286 | Unary {{zero?}}. |
---|
1287 | Yields {{'#t}} if the list is empty, otherwise yields {{'#f}}. |
---|
1288 | Same as {{c-null?}}. |
---|
1289 | |
---|
1290 | <enscript highlight="scheme"> |
---|
1291 | (ck () (c-quote (c-uzero? '()))) |
---|
1292 | ;; ==> '#t |
---|
1293 | (ck () (c-quote (c-uzero? '(a)))) |
---|
1294 | ;; ==> '#f |
---|
1295 | </enscript> |
---|
1296 | |
---|
1297 | |
---|
1298 | <syntax>(c-ueven? U) â '#t or '#f</syntax> |
---|
1299 | |
---|
1300 | Unary {{even?}}. |
---|
1301 | Yields {{'#t}} if the given list's length is even |
---|
1302 | (i.e. a multiple of 2), otherwise yields {{'#f}}. |
---|
1303 | |
---|
1304 | <enscript highlight="scheme"> |
---|
1305 | (ck () (c-quote (c-ueven? '()))) |
---|
1306 | ;; ==> '#t |
---|
1307 | (ck () (c-quote (c-ueven? '(a)))) |
---|
1308 | ;; ==> '#f |
---|
1309 | (ck () (c-quote (c-ueven? '(a b)))) |
---|
1310 | ;; ==> '#t |
---|
1311 | </enscript> |
---|
1312 | |
---|
1313 | |
---|
1314 | <syntax>(c-uodd? U) â '#t or '#f</syntax> |
---|
1315 | |
---|
1316 | Unary {{odd?}}. |
---|
1317 | Yields {{'#t}} if the given list's length is odd |
---|
1318 | (i.e. not a multiple of 2), otherwise yields {{'#f}}. |
---|
1319 | |
---|
1320 | <enscript highlight="scheme"> |
---|
1321 | (ck () (c-quote (c-uodd? '()))) |
---|
1322 | ;; ==> '#f |
---|
1323 | (ck () (c-quote (c-uodd? '(a)))) |
---|
1324 | ;; ==> '#t |
---|
1325 | (ck () (c-quote (c-uodd? '(a b)))) |
---|
1326 | ;; ==> '#f |
---|
1327 | </enscript> |
---|
1328 | |
---|
1329 | |
---|
1330 | <syntax>(c-u+ U1 U2) â list</syntax> |
---|
1331 | |
---|
1332 | Unary addition. |
---|
1333 | Same as {{c-append}}. |
---|
1334 | This was named {{c-add}} in the original implementation. |
---|
1335 | |
---|
1336 | <enscript highlight="scheme"> |
---|
1337 | (ck () (c-quote (c-u+ '(a b) '(c)))) |
---|
1338 | ;; ==> '(a b c) |
---|
1339 | </enscript> |
---|
1340 | |
---|
1341 | |
---|
1342 | <syntax>(c-u- U1 U2) â list</syntax> |
---|
1343 | |
---|
1344 | Unary subtraction. |
---|
1345 | Drops an element from the front of the first list for each element in second list, |
---|
1346 | then yields the remaining list. |
---|
1347 | Negative numbers cannot be represented in unary, |
---|
1348 | so this yields '() if the second list is equal or longer than the first. |
---|
1349 | |
---|
1350 | <enscript highlight="scheme"> |
---|
1351 | (ck () (c-quote (c-u- (c-list 'a 'b 'c 'd) '(x y)))) |
---|
1352 | ;; ==> '(c d) |
---|
1353 | |
---|
1354 | (ck () (c-quote (c-u- (c-list 'a 'b) (c-list 'x 'y 'z)))) |
---|
1355 | ;; ==> '() |
---|
1356 | ;; Because negative numbers cannot be represented in unary. |
---|
1357 | </enscript> |
---|
1358 | |
---|
1359 | |
---|
1360 | <syntax>(c-u* U1 U2) â list</syntax> |
---|
1361 | |
---|
1362 | Unary multiplication. |
---|
1363 | Yields a list containing the contents of the first list, |
---|
1364 | repeated once for every item in the second list. |
---|
1365 | |
---|
1366 | Based on {{c-mul}} from the original implementation, |
---|
1367 | except the symbol 'u has no special significance, |
---|
1368 | and result is made from duplicating the first list. |
---|
1369 | |
---|
1370 | <enscript highlight="scheme"> |
---|
1371 | (ck () (c-quote (c-u* '(a b) '(c d e)))) |
---|
1372 | ;; ==> '(a b a b a b) |
---|
1373 | </enscript> |
---|
1374 | |
---|
1375 | |
---|
1376 | <syntax>(c-u/ U1 U2) â list</syntax> |
---|
1377 | |
---|
1378 | Unary division. |
---|
1379 | Yields a list of two unary numbers, |
---|
1380 | representing the quotient and the remainder of the division. |
---|
1381 | |
---|
1382 | Given the second list has length {{N}}, |
---|
1383 | the quotient will contain every {{N}}th item from the first list, |
---|
1384 | and the remainder will contain the tail of the first list. |
---|
1385 | Division by zero (empty list) is a syntax error. |
---|
1386 | |
---|
1387 | <enscript highlight="scheme"> |
---|
1388 | (ck () (c-quote (c-u/ '(a b c d e f g h i j k) |
---|
1389 | '(x y z)))) |
---|
1390 | ;; ==> '((g d a) (j k)) |
---|
1391 | ;; Because 11 / 3 = 3 with a remainder of 2. |
---|
1392 | </enscript> |
---|
1393 | |
---|
1394 | |
---|
1395 | <syntax>(c-ufactorial U) â list</syntax> |
---|
1396 | |
---|
1397 | Unary factorial. |
---|
1398 | If the given list has length zero, yields the list {{'(u)}}. |
---|
1399 | If the given list has length one, yields the given list. |
---|
1400 | Otherwise, yields a list containing items of the given list repeated {{(N-1)!}} times, |
---|
1401 | where {{N}} is the length of the given list. |
---|
1402 | This was named {{c-fact}} in the original implementation. |
---|
1403 | |
---|
1404 | <enscript highlight="scheme"> |
---|
1405 | (ck () (c-quote (c-ufactorial '(a b c)))) |
---|
1406 | ;; ==> '(a b c a b c) |
---|
1407 | ;; Because 3! = 6. |
---|
1408 | </enscript> |
---|
1409 | |
---|
1410 | |
---|
1411 | <syntax>(c-udrop L U) â list</syntax> |
---|
1412 | |
---|
1413 | Drops up to U items from the front of the given list, |
---|
1414 | where U is a unary number. |
---|
1415 | |
---|
1416 | Same as {{c-u-}}. |
---|
1417 | Analogous to {{drop}} from SRFI 1, |
---|
1418 | but uses unary numbers, |
---|
1419 | and yields empty list if the list is too short. |
---|
1420 | |
---|
1421 | <enscript highlight="scheme"> |
---|
1422 | (ck () (c-quote (c-udrop (c-list 'a 'b 'c 'd) '(x y)))) |
---|
1423 | ;; ==> '(c d) |
---|
1424 | (ck () (c-quote (c-udrop (c-list 'a 'b) (c-list 'x 'y 'z)))) |
---|
1425 | ;; ==> '() |
---|
1426 | </enscript> |
---|
1427 | |
---|
1428 | |
---|
1429 | <syntax>(c-utake L U) â list</syntax> |
---|
1430 | |
---|
1431 | Yields a list containing up to U items from the front of the given list, |
---|
1432 | where U is a unary number. |
---|
1433 | |
---|
1434 | Analogous to {{take}} from SRFI 1, |
---|
1435 | but uses unary numbers, |
---|
1436 | and yields the entire list if it is too short. |
---|
1437 | |
---|
1438 | <enscript highlight="scheme"> |
---|
1439 | (ck () (c-quote (c-utake '(a b c d) '(x y z)))) |
---|
1440 | ;; ==> '(a b c) |
---|
1441 | (ck () (c-quote (c-utake '(a b) '(x y z)))) |
---|
1442 | ;; ==> '(a b) |
---|
1443 | </enscript> |
---|
1444 | |
---|
1445 | |
---|
1446 | |
---|
1447 | === Non-portable R5RS Wrappers |
---|
1448 | |
---|
1449 | These are CK-macros that wrap some R5RS procedures that are useful for building macros. |
---|
1450 | Not every R5RS procedure is provided here. |
---|
1451 | If you need other procedures, use [[#ck-wrapper|{{ck-wrapper}}]] |
---|
1452 | to create your own wrappers. |
---|
1453 | |
---|
1454 | These wrappers are considered non-portable because they use ck-wrapper, |
---|
1455 | which is not portable to all R5RS Scheme implementations. |
---|
1456 | See the ck-wrapper docs for portability information. |
---|
1457 | |
---|
1458 | Some R5RS procedures have portable, non-wrapper CK-macro equivalents, |
---|
1459 | which are described in the [[#portable-ck-macros|Portable CK-macros]] section, above. |
---|
1460 | For example, there is no wrapper for {{pair?}} listed below, |
---|
1461 | because {{c-pair?}} is a portable CK-macro listed above. |
---|
1462 | |
---|
1463 | |
---|
1464 | ==== General (R5RS Wrappers) |
---|
1465 | |
---|
1466 | <syntax>(c-eqv? X Y) â '#t or '#f</syntax> |
---|
1467 | |
---|
1468 | CK-macro wrapper for {{eqv?}}. |
---|
1469 | Added in '''version 0.2.0'''. |
---|
1470 | |
---|
1471 | <syntax>(c-eq? X Y) â '#t or '#f</syntax> |
---|
1472 | |
---|
1473 | CK-macro wrapper for {{eq?}}. |
---|
1474 | Added in '''version 0.2.0'''. |
---|
1475 | |
---|
1476 | <syntax>(c-equal? X Y) â '#t or '#f</syntax> |
---|
1477 | |
---|
1478 | CK-macro wrapper for {{equal?}}. |
---|
1479 | Added in '''version 0.2.0'''. |
---|
1480 | |
---|
1481 | |
---|
1482 | ==== Numbers and Math (R5RS Wrappers) |
---|
1483 | |
---|
1484 | <syntax>(c-number? X) â '#t or '#f</syntax> |
---|
1485 | |
---|
1486 | CK-macro wrapper for {{number?}}. |
---|
1487 | Added in '''version 0.2.0'''. |
---|
1488 | |
---|
1489 | <syntax>(c-integer? X) â '#t or '#f</syntax> |
---|
1490 | |
---|
1491 | CK-macro wrapper for {{integer?}}. |
---|
1492 | Added in '''version 0.2.0'''. |
---|
1493 | |
---|
1494 | <syntax>(c-= N ...) â '#t or '#f</syntax> |
---|
1495 | |
---|
1496 | CK-macro wrapper for {{=}} (equal). |
---|
1497 | Added in '''version 0.2.0'''. |
---|
1498 | |
---|
1499 | <syntax>(c-< N ...) â '#t or '#f</syntax> |
---|
1500 | |
---|
1501 | CK-macro wrapper for {{<}} (less than). |
---|
1502 | Added in '''version 0.2.0'''. |
---|
1503 | |
---|
1504 | <syntax>(c-> N ...) â '#t or '#f</syntax> |
---|
1505 | |
---|
1506 | CK-macro wrapper for {{>}} (greater than). |
---|
1507 | Added in '''version 0.2.0'''. |
---|
1508 | |
---|
1509 | <syntax>(c-<= N ...) â '#t or '#f</syntax> |
---|
1510 | |
---|
1511 | CK-macro wrapper for {{<=}} (less than or equal). |
---|
1512 | Added in '''version 0.2.0'''. |
---|
1513 | |
---|
1514 | <syntax>(c->= N ...) â '#t or '#f</syntax> |
---|
1515 | |
---|
1516 | CK-macro wrapper for {{>=}} (greater than or equal). |
---|
1517 | Added in '''version 0.2.0'''. |
---|
1518 | |
---|
1519 | <syntax>(c-max N ...) â number</syntax> |
---|
1520 | |
---|
1521 | CK-macro wrapper for {{max}}. |
---|
1522 | Added in '''version 0.2.0'''. |
---|
1523 | |
---|
1524 | <syntax>(c-min N ...) â number</syntax> |
---|
1525 | |
---|
1526 | CK-macro wrapper for {{min}}. |
---|
1527 | Added in '''version 0.2.0'''. |
---|
1528 | |
---|
1529 | <syntax>(c-+ N ...) â number</syntax> |
---|
1530 | |
---|
1531 | CK-macro wrapper for {{+}} (addition). |
---|
1532 | Added in '''version 0.2.0'''. |
---|
1533 | |
---|
1534 | <syntax>(c-* N ...) â number</syntax> |
---|
1535 | |
---|
1536 | CK-macro wrapper for {{*}} (multiplication). |
---|
1537 | Added in '''version 0.2.0'''. |
---|
1538 | |
---|
1539 | <syntax>(c-- N ...) â number</syntax> |
---|
1540 | |
---|
1541 | CK-macro wrapper for {{-}} (subtraction). |
---|
1542 | Added in '''version 0.2.0'''. |
---|
1543 | |
---|
1544 | <syntax>(c-/ N ...) â number</syntax> |
---|
1545 | |
---|
1546 | CK-macro wrapper for {{/}} (division). |
---|
1547 | Added in '''version 0.2.0'''. |
---|
1548 | |
---|
1549 | <syntax>(c-remainder N1 N2) â number</syntax> |
---|
1550 | |
---|
1551 | CK-macro wrapper for {{remainder}}. |
---|
1552 | Added in '''version 0.2.0'''. |
---|
1553 | |
---|
1554 | <syntax>(c-floor N) â number</syntax> |
---|
1555 | |
---|
1556 | CK-macro wrapper for {{floor}}. |
---|
1557 | Added in '''version 0.2.0'''. |
---|
1558 | |
---|
1559 | <syntax>(c-round N) â number</syntax> |
---|
1560 | |
---|
1561 | CK-macro wrapper for {{round}}. |
---|
1562 | Added in '''version 0.2.0'''. |
---|
1563 | |
---|
1564 | <syntax>(c-exact->inexact N) â inexact number</syntax> |
---|
1565 | |
---|
1566 | CK-macro wrapper for {{exact->inexact}}. |
---|
1567 | Added in '''version 0.2.0'''. |
---|
1568 | |
---|
1569 | <syntax>(c-inexact->exact N) â exact number</syntax> |
---|
1570 | |
---|
1571 | CK-macro wrapper for {{inexact->exact}}. |
---|
1572 | Added in '''version 0.2.0'''. |
---|
1573 | |
---|
1574 | <syntax>(c-number->string N) â string</syntax> |
---|
1575 | <syntax>(c-number->string N RADIX) â string</syntax> |
---|
1576 | |
---|
1577 | CK-macro wrapper for {{number->string}}. |
---|
1578 | Added in '''version 0.2.0'''. |
---|
1579 | |
---|
1580 | <syntax>(c-string->number STR) â number or '#f</syntax> |
---|
1581 | <syntax>(c-string->number STR RADIX) â number or '#f</syntax> |
---|
1582 | |
---|
1583 | CK-macro wrapper for {{string->number}}. |
---|
1584 | Added in '''version 0.2.0'''. |
---|
1585 | |
---|
1586 | |
---|
1587 | ==== Pairs and Lists (R5RS Wrappers) |
---|
1588 | |
---|
1589 | <syntax>(c-length L) â integer</syntax> |
---|
1590 | |
---|
1591 | CK-macro wrapper for {{length}}. |
---|
1592 | Added in '''version 0.2.0'''. |
---|
1593 | |
---|
1594 | <syntax>(c-list-ref L I) â item</syntax> |
---|
1595 | |
---|
1596 | CK-macro wrapper for {{list-ref}}. |
---|
1597 | Added in '''version 0.2.0'''. |
---|
1598 | |
---|
1599 | |
---|
1600 | ==== Symbols (R5RS Wrappers) |
---|
1601 | |
---|
1602 | <syntax>(c-symbol? X) â '#t or '#f</syntax> |
---|
1603 | |
---|
1604 | CK-macro wrapper for {{symbol?}}. |
---|
1605 | Added in '''version 0.2.0'''. |
---|
1606 | |
---|
1607 | <syntax>(c-symbol->string SYM) â string</syntax> |
---|
1608 | |
---|
1609 | CK-macro wrapper for {{symbol->string}}. |
---|
1610 | Added in '''version 0.2.0'''. |
---|
1611 | |
---|
1612 | <syntax>(c-string->symbol STR) â symbol</syntax> |
---|
1613 | |
---|
1614 | CK-macro wrapper for {{string->symbol}}. |
---|
1615 | Added in '''version 0.2.0'''. |
---|
1616 | |
---|
1617 | |
---|
1618 | ==== Chars and Strings (R5RS Wrappers) |
---|
1619 | |
---|
1620 | <syntax>(c-char? CHAR ...) â '#t or '#f</syntax> |
---|
1621 | |
---|
1622 | CK-macro wrapper for {{char?}}. |
---|
1623 | Added in '''version 0.2.0'''. |
---|
1624 | |
---|
1625 | <syntax>(c-char=? CHAR ...) â '#t or '#f</syntax> |
---|
1626 | |
---|
1627 | CK-macro wrapper for {{char=?}}. |
---|
1628 | Added in '''version 0.2.0'''. |
---|
1629 | |
---|
1630 | <syntax>(c-string? X) â '#t or '#f</syntax> |
---|
1631 | |
---|
1632 | CK-macro wrapper for {{string?}}. |
---|
1633 | Added in '''version 0.2.0'''. |
---|
1634 | |
---|
1635 | <syntax>(c-string CHAR ...) â string</syntax> |
---|
1636 | |
---|
1637 | CK-macro wrapper for {{string}}. |
---|
1638 | Added in '''version 0.2.0'''. |
---|
1639 | |
---|
1640 | <syntax>(c-string-length STR) â integer</syntax> |
---|
1641 | |
---|
1642 | CK-macro wrapper for {{string-length}}. |
---|
1643 | Added in '''version 0.2.0'''. |
---|
1644 | |
---|
1645 | <syntax>(c-string-ref STR I) â char</syntax> |
---|
1646 | |
---|
1647 | CK-macro wrapper for {{string-ref}}. |
---|
1648 | Added in '''version 0.2.0'''. |
---|
1649 | |
---|
1650 | <syntax>(c-string=? STR ...) â '#t or '#f</syntax> |
---|
1651 | |
---|
1652 | CK-macro wrapper for {{string=?}}. |
---|
1653 | Added in '''version 0.2.0'''. |
---|
1654 | |
---|
1655 | <syntax>(c-string-ci=? STR ...) â '#t or '#f</syntax> |
---|
1656 | |
---|
1657 | CK-macro wrapper for {{string-ci=?}}. |
---|
1658 | Added in '''version 0.2.0'''. |
---|
1659 | |
---|
1660 | <syntax>(c-substring STR START) â string</syntax> |
---|
1661 | <syntax>(c-substring STR START END) â string</syntax> |
---|
1662 | |
---|
1663 | CK-macro wrapper for {{substring}}. |
---|
1664 | Added in '''version 0.2.0'''. |
---|
1665 | |
---|
1666 | <syntax>(c-string-append STR ...) â string</syntax> |
---|
1667 | |
---|
1668 | CK-macro wrapper for {{string-append}}. |
---|
1669 | Added in '''version 0.2.0'''. |
---|
1670 | |
---|
1671 | |
---|
1672 | ==== Vectors (R5RS Wrappers) |
---|
1673 | |
---|
1674 | <syntax>(c-vector-length V) â integer</syntax> |
---|
1675 | |
---|
1676 | CK-macro wrapper for {{vector-length}}. |
---|
1677 | Added in '''version 0.2.0'''. |
---|
1678 | |
---|
1679 | <syntax>(c-vector-ref V I) â item</syntax> |
---|
1680 | |
---|
1681 | CK-macro wrapper for {{vector-ref}}. |
---|
1682 | Added in '''version 0.2.0'''. |
---|