@@ -222,35 +222,47 @@ <h3 id="vector-transduce">vector-transduce</h3>
222
222
< br />
223
223
< code > (vector-transduce</ code > < em > xform f identity vec</ em > < code > )</ code > </ p >
224
224
225
- < p > Same as < code > transduce</ code > , but reduces over a vector instead of a list.</ p >
225
+ < p > Same as < code > list- transduce</ code > , but reduces over a vector instead of a list.</ p >
226
226
227
227
228
228
< h3 id ="string-transduce "> string-transduce</ h3 >
229
229
< p > < code > (string-transduce</ code > < em > xform f str</ em > < code > )</ code >
230
230
< br />
231
231
< code > (string-transduce</ code > < em > xform f identity str</ em > < code > )</ code > </ p >
232
232
233
- < p > Same as < code > transduce</ code > , but for strings.</ p >
233
+ < p > Same as < code > list- transduce</ code > , but for strings.</ p >
234
234
235
235
236
236
< h3 id ="bytevector-u8-transduce "> bytevector-u8-transduce</ h3 >
237
237
< p > < code > (bytevector-u8-transduce</ code > < em > xform f bvec</ em > < code > )</ code >
238
238
< br />
239
239
< code > (bytevector-u8-transduce</ code > < em > xform f identity bvec</ em > < code > )</ code > </ p >
240
240
241
- < p > Same as transduce, but for u8-bytevectors.</ p >
241
+ < p > Same as < code > list- transduce</ code > , but for u8-bytevectors.</ p >
242
242
243
243
244
244
< h3 id ="port-transduce "> port-transduce</ h3 >
245
- < p > < code > (port-transduce</ code > < em > xform f reader port</ em > < code > )</ code >
246
- < br />
247
- < code > (port-transduce</ code > < em > xform f init reader port</ em > < code > )</ code > </ p >
248
-
249
- < p > Applies < code > (xform f)</ code > to every value produced by < code > (reader port)</ code > until
250
- < code > #eof-object</ code > is returned.</ p >
245
+ < p > < code > (port-transduce</ code > < em > xform f reader</ em > < code > )</ code >
246
+ < br />
247
+ < code > (port-transduce</ code > < em > xform f reader port</ em > < code > )</ code >
248
+ < br />
249
+ < code > (port-transduce</ code > < em > xform f init reader port</ em > < code > )</ code > </ p >
250
+
251
+ < p > If < em > port</ em > is provided, it applies < code > (xform f)</ code > to every value
252
+ produced by < code > (reader port)</ code > until < code > #eof-object</ code > is returned.
253
+ If < em > port</ em > is not provided, it calls < em > reader</ em > without arguments until
254
+ < code > #eof-object</ code > is returned.
255
+ </ p >
251
256
252
257
< p > < code > (port-transduce (tfilter odd?) rcons read (open-input-string "1 2 3 4"))</ code >
253
- => (2 4)</ p >
258
+ => (2 4)</ p >
259
+
260
+ < h3 id ="generator-transduce "> generator-transduce</ h3 >
261
+ < p > < code > (generator-transduce</ code > < em > xform f gen</ em > < code > )</ code >
262
+ < br />
263
+ < code > (generator-transduce</ code > < em > xform f init gen</ em > < code > )</ code > </ p >
264
+
265
+ < p > Same as list-transduce, but for srfi-158-styled generators</ p >
254
266
255
267
256
268
< h2 id ="reducers "> Reducers</ h2 >
@@ -289,7 +301,7 @@ <h3 id="revery-pred"><code>(revery</code> <em>pred?</em><code>)</code></h3>
289
301
< p > The reducer version of every. Stops the transduction and returns
290
302
(reduced #f) if any (pred? value) returns #f. If every (pred? value)
291
303
returns true, it returns the result of the last invocation of (pred?
292
- value).</ p >
304
+ value). The identity is < code > #t </ code > .</ p >
293
305
294
306
< p > < pre > (list-transduce
295
307
(tmap (lambda (x) (+ x 1)))
@@ -329,13 +341,17 @@ <h3 id="tfilter-map-proc"><code>(tfilter-map</code> <em>proc</em><code>)</code><
329
341
Must be stateless.</ p >
330
342
331
343
332
- < h3 id ="treplace-map "> < code > (treplace</ code > < em > map </ em > < code > )</ code > </ h3 >
333
- < p > Returns a transducer which uses any value as a key in
334
- < em > map </ em > . If a mapping is found, the value of that mapping is
335
- returned, otherwise it just returns the original value.</ p >
344
+ < h3 id ="treplace-mapping "> < code > (treplace</ code > < em > mapping </ em > < code > )</ code > </ h3 >
345
+ < p > Returns a transducer which checks for the presence of any value passed through it in
346
+ < em > mapping </ em > . If a mapping is found, the value of that mapping is
347
+ returned, otherwise it just returns the original value.</ p >
336
348
337
- < p > Must not keep any internal state. Modifying the map after treplace
338
- has been instantiated is an error.</ p >
349
+ < p > < em > mapping</ em > is an association list (using equal? to compare keys), a hash-table,
350
+ a one-argument procedure taking one argument and either producing that same argument
351
+ or a replacement value, or another implementation-defined mapping object.</ p >
352
+
353
+ < p > Must not keep any internal state. Modifying the mapping while it's in use by treplace
354
+ is an error.</ p >
339
355
340
356
341
357
< h3 id ="tdrop-n "> < code > (tdrop</ code > < em > n</ em > < code > )</ code > </ h3 >
@@ -392,7 +408,7 @@ <h3 id="tflatten"><code>tflatten</code></h3>
392
408
393
409
394
410
395
- < h3 id ="tdelete-neighbor-dupes "> < code > (tdelete-neighbour -dupes < em > [equality-predicate]</ em > )</ code > </ h3 >
411
+ < h3 id ="tdelete-neighbor-dupes "> < code > (tdelete-neighbor -dupes < em > [equality-predicate]</ em > )</ code > </ h3 >
396
412
< p > Returns a transducer that removes any directly following duplicate
397
413
elements. The default < em > equality-predicate</ em > is < code > equal?</ code > .</ p >
398
414
@@ -500,20 +516,25 @@ <h3 id="string-reduce"><code>(string-reduce</code> <em> f identity str</em><code
500
516
< p > The string version of < code > list-reduce</ code > </ p >
501
517
502
518
503
- < h3 id ="string -reduce "> < code > (port-reduce</ code > < em > f identity reader port</ em > < code > )</ code > </ h3 >
519
+ < h3 id ="port -reduce "> < code > (port-reduce</ code > < em > f identity reader port</ em > < code > )</ code > </ h3 >
504
520
< p > The port version of < code > list-reducer</ code > . It reduces over < em > port</ em > using
505
521
< em > reader</ em > until < em > reader</ em > returns < code > #eof-object</ code > .</ p >
506
522
507
523
524
+ < h3 id ="generator-reduce "> < code > (generator-reduce</ code > < em > f identity gen</ em > < code > )</ code > </ h3 >
525
+ < p > The port version of < code > list-reducer</ code > . It reduces over < em > gen</ em > until it returns
526
+
527
+ < code > #eof-object</ code > .</ p >
528
+
508
529
509
530
< h1 id ="sample-implementation "> Sample implementation</ h1 >
510
531
511
532
< p > The sample implementation is written in Guile, but should be
512
- straightforward to port since it uses no guile-specific features
513
- apart from guile's hash-table implementation. In fact, I am quite
514
- certain that it is written for clarity instead of speed, but should
515
- be plenty fast anyway. The low-hanging fruit for optimization is to
516
- replace the composed transducers (such as < code > tappend-map</ code >
533
+ straightforward to port since it uses no guile-specific features
534
+ apart from guile's hash-table implementation. In fact, I am quite
535
+ certain that it is written for clarity instead of speed, but should
536
+ be plenty fast anyway. The low-hanging fruit for optimization is to
537
+ replace the composed transducers (such as < code > tappend-map</ code >
517
538
and < code > tfilter-map</ code > ) with non-composed implementations.</ p >
518
539
519
540
< p > Another optimization would be to return whether or not a reducer
@@ -523,43 +544,48 @@ <h1 id="sample-implementation">Sample implementation</h1>
523
544
524
545
< h1 id ="acknowledgements "> Acknowledgements</ h1 >
525
546
526
- < p > First of all, this would not have been done without Rich Hickey who
527
- introduced transducers into Clojure. His talks were important for me
528
- to grasp the basics of transducers. Then I would like to thank large
529
- parts of the Clojure community for also struggling with
530
- understanding transducers. The amount of material produced
531
- explaining them in general, and Clojure's implementation
532
- specifically, has been instrumental in letting me make this a
547
+ < p > First of all, this would not have been done without Rich Hickey who
548
+ introduced transducers into Clojure. His talks were important for me
549
+ to grasp the basics of transducers. Then I would like to thank large
550
+ parts of the Clojure community for also struggling with
551
+ understanding transducers. The amount of material produced
552
+ explaining them in general, and Clojure's implementation
553
+ specifically, has been instrumental in letting me make this a
533
554
clean-room implementation.</ p >
534
555
535
- < p > I'd also like to thank Juanpe Bolivar who implemented pure transducers
536
- for c++ (in the Atria library) and did a wonderful presentation about them.</ p >
556
+ < p > In the same vein I would like to direct a thank you to Juanpe Bolivar who
557
+ implemented pure transducers for c++ (in the Atria library) and did a
558
+ wonderful presentation about them.</ p >
559
+
560
+ < p > I would also like to thank John Cowan, Duy Nguyen and Lassi Kortela for
561
+ their input during the SRFI process. </ p >
537
562
538
563
< p > Lastly I would like to thank Arthur Gleckler who showed interest in
539
564
my implementation of transducers and convinced me to make this SRFI.</ p >
540
565
566
+
541
567
< h1 id ="copyright "> Copyright</ h1 >
542
568
543
- < p > Copyright (C) Linus Björnstam (2019).</ p >
544
-
545
- < p > Permission is hereby granted, free of charge, to any person
546
- obtaining a copy of this software and associated documentation files
547
- (the “Software”), to deal in the Software without restriction,
548
- including without limitation the rights to use, copy, modify, merge,
549
- publish, distribute, sublicense, and/or sell copies of the Software,
550
- and to permit persons to whom the Software is furnished to do so,
551
- subject to the following conditions:</ p >
552
-
553
- < p > The above copyright notice and this permission notice shall be
554
- included in all copies or substantial portions of the Software.</ p >
555
-
556
- < p > THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
557
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
558
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
559
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
560
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
561
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
562
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
563
- SOFTWARE.</ p >
569
+ < p > Copyright (C) Linus Björnstam (2019).</ p >
570
+
571
+ < p > Permission is hereby granted, free of charge, to any person
572
+ obtaining a copy of this software and associated documentation files
573
+ (the “Software”), to deal in the Software without restriction,
574
+ including without limitation the rights to use, copy, modify, merge,
575
+ publish, distribute, sublicense, and/or sell copies of the Software,
576
+ and to permit persons to whom the Software is furnished to do so,
577
+ subject to the following conditions:</ p >
578
+
579
+ < p > The above copyright notice and this permission notice shall be
580
+ included in all copies or substantial portions of the Software.</ p >
581
+
582
+ < p > THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
583
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
584
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
585
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
586
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
587
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
588
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
589
+ SOFTWARE.</ p >
564
590
565
591
< hr > < address > Editor: < a href ="mailto:srfi-editors+at+srfi+dot+schemers+dot+org "> Arthur A. Gleckler</ a > </ address > </ body > </ html >
0 commit comments