Skip to content

Commit 9c84bcd

Browse files
committed
Fix portability issues
This makes the reference implementation pass on Gauche, Chibi and Guile. - tindex unexported because it's not implemented (nor documented in the SRFI). - avoid unportable [ ] in the implementation - correct reverse-rcons name - add r7rs boilderplate to build with both chibi and gauche (chibi will use (rapid test) since (srfi 64) is not available) Open issues: tflatten, tpartition-all, tindex and possibly the TODO comment in "reducers" test block (should be fixed before finalizing?)
1 parent dec3665 commit 9c84bcd

10 files changed

+237
-109
lines changed

srfi-171.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,14 @@ <h3 id="tconcatenate"><code>tconcatenate</code></h3>
380380

381381

382382
<h3 id="tappend-map-proc"><code>(tappend-map</code> <em>proc</em><code>)</code></h3>
383-
<p>The same as <code>(compose (tmap proc) tcat)</code>.</p>
383+
<p>The same as <code>(compose (tmap proc) tconcatenate)</code>.</p>
384384

385385

386386
<h3 id="tflatten"><code>tflatten</code></h3>
387387
<p><code>tflatten</code> <strong>is</strong> a transducer that flattens an input
388388
consisting of lists.</p>
389389

390-
<p><code>(list-transduce (tflatten) rcons '((1 2) 3 (4 (5 6) 7 8) 9)</code> =&gt;
390+
<p><code>(list-transduce tflatten rcons '((1 2) 3 (4 (5 6) 7 8) 9)</code> =&gt;
391391
<code>(1 2 3 4 5 6 7 8 9)</code></p>
392392

393393

srfi/171-impl.scm

+7-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
((lst x) (cons x lst))))
5252

5353

54-
(define reverse-rconj
54+
(define reverse-rcons
5555
(case-lambda
5656
(() '())
5757
((lst) lst)
@@ -183,7 +183,7 @@
183183
x))))
184184
((hash-table? map)
185185
(lambda (x)
186-
(hash-ref map x x)))))
186+
(hash-table-ref map x x)))))
187187

188188

189189
(define (treplace map)
@@ -304,16 +304,16 @@
304304
(() (tdelete-duplicates equal?))
305305
((equality-pred?)
306306
(lambda (reducer)
307-
(let ([already-seen (make-hash-table equality-pred?)])
307+
(let ((already-seen (make-hash-table equality-pred?)))
308308
(case-lambda
309-
[() (reducer)]
310-
[(result) (reducer result)]
311-
[(result input)
309+
(() (reducer))
310+
((result) (reducer result))
311+
((result input)
312312
(if (hash-table-exists? already-seen input)
313313
result
314314
(begin
315315
(hash-table-set! already-seen input #t)
316-
(reducer result input)))]))))))
316+
(reducer result input))))))))))
317317

318318
;; Partitions the input into lists of N items. If the input stops it flushes whatever
319319
;; it has collected, which may be shorter than n.

srfi/171.sld

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2+
;; Copyright 2019 Linus Björnstam
3+
;;
4+
;; You may use this code under either the license in the SRFI document or the
5+
;; license below.
6+
;;
7+
;; Permission to use, copy, modify, and/or distribute this software for any
8+
;; purpose with or without fee is hereby granted, provided that the above
9+
;; copyright notice and this permission notice appear in all source copies.
10+
;; The software is provided "as is", without any express or implied warranties.
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
13+
14+
(define-library (srfi 171)
15+
(import (scheme base)
16+
(scheme case-lambda)
17+
(scheme write)
18+
(srfi 9)
19+
(only (scheme vector) vector->list)
20+
(srfi 69)
21+
(srfi 171 meta))
22+
(cond-expand
23+
(gauche (import (only (gauche base) compose reverse!)))
24+
(chibi (import (only (srfi 1) reverse!))))
25+
(export rcons reverse-rcons
26+
rcount
27+
rany
28+
revery
29+
30+
list-transduce
31+
vector-transduce
32+
string-transduce
33+
bytevector-u8-transduce
34+
port-transduce
35+
36+
tmap
37+
tfilter
38+
tremove
39+
treplace
40+
tfilter-map
41+
tdrop
42+
tdrop-while
43+
ttake
44+
ttake-while
45+
tconcatenate
46+
tappend-map
47+
tdelete-neighbor-dupes
48+
tdelete-duplicates
49+
tflatten
50+
tsegment
51+
tpartition
52+
tinterpose
53+
tlog)
54+
55+
;; compose.scm uses fold-left, not available in
56+
;; Chibi. This is all we need for this SRFI
57+
(cond-expand
58+
(chibi (begin (define compose
59+
(lambda (f g)
60+
(lambda args
61+
(f (apply g args)))))))
62+
(else (begin)))
63+
64+
(include "171-impl.scm"))

srfi/171/meta.sld

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2+
;; Copyright 2019 Linus Björnstam
3+
;;
4+
;; You may use this code under either the license in the SRFI document or the
5+
;; license below.
6+
;;
7+
;; Permission to use, copy, modify, and/or distribute this software for any
8+
;; purpose with or without fee is hereby granted, provided that the above
9+
;; copyright notice and this permission notice appear in all source copies.
10+
;; The software is provided "as is", without any express or implied warranties.
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
13+
(define-library (srfi 171 meta)
14+
(import (scheme base) (srfi 9))
15+
(export reduced reduced?
16+
unreduce
17+
ensure-reduced
18+
preserving-reduced
19+
20+
list-reduce
21+
vector-reduce
22+
string-reduce
23+
bytevector-u8-reduce
24+
port-reduce)
25+
26+
(include "../srfi-171-meta.scm"))
27+
28+

srfi/srfi-171-meta.scm

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2+
;; Copyright 2019 Linus Björnstam
3+
;;
4+
;; You may use this code under either the license in the SRFI document or the
5+
;; license below.
6+
;;
7+
;; Permission to use, copy, modify, and/or distribute this software for any
8+
;; purpose with or without fee is hereby granted, provided that the above
9+
;; copyright notice and this permission notice appear in all source copies.
10+
;; The software is provided "as is", without any express or implied warranties.
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
13+
;; A reduced value is stops the transduction.
14+
(define-record-type <reduced>
15+
(reduced val)
16+
reduced?
17+
(val unreduce))
18+
19+
20+
;; helper function which ensures x is reduced.
21+
(define (ensure-reduced x)
22+
(if (reduced? x)
23+
x
24+
(reduced x)))
25+
26+
27+
;; helper function that wraps a reduced value twice since reducing functions (like list-reduce)
28+
;; unwraps them. tconcatenate is a good example: it re-uses it's reducer on it's input using list-reduce.
29+
;; If that reduction finishes early and returns a reduced value, list-reduce would "unreduce"
30+
;; that value and try to continue the transducing process.
31+
(define (preserving-reduced reducer)
32+
(lambda (a b)
33+
(let ((return (reducer a b)))
34+
(if (reduced? return)
35+
(reduced return)
36+
return))))
37+
38+
39+
;; This is where the magic tofu is cooked
40+
(define (list-reduce f identity lst)
41+
(if (null? lst)
42+
identity
43+
(let ((v (f identity (car lst))))
44+
(if (reduced? v)
45+
(unreduce v)
46+
(list-reduce f v (cdr lst))))))
47+
48+
(define (vector-reduce f identity vec)
49+
(let ((len (vector-length vec)))
50+
(let loop ((i 0) (acc identity))
51+
(if (= i len)
52+
acc
53+
(let ((acc (f acc (vector-ref vec i))))
54+
(if (reduced? acc)
55+
(unreduce acc)
56+
(loop (+ i 1) acc)))))))
57+
58+
(define (string-reduce f identity str)
59+
(let ((len (string-length str)))
60+
(let loop ((i 0) (acc identity))
61+
(if (= i len)
62+
acc
63+
(let ((acc (f acc (string-ref str i))))
64+
(if (reduced? acc)
65+
(unreduce acc)
66+
(loop (+ i 1) acc)))))))
67+
68+
(define (bytevector-u8-reduce f identity vec)
69+
(let ((len (bytevector-length vec)))
70+
(let loop ((i 0) (acc identity))
71+
(if (= i len)
72+
acc
73+
(let ((acc (f acc (bytevector-u8-ref vec i))))
74+
(if (reduced? acc)
75+
(unreduce acc)
76+
(loop (+ i 1) acc)))))))
77+
78+
(define (port-reduce f identity reader port)
79+
(let loop ((val (reader port)) (acc identity))
80+
(if (eof-object? val)
81+
acc
82+
(let ((acc (f acc val)))
83+
(if (reduced? acc)
84+
(unreduce acc)
85+
(loop (reader port) acc))))))

srfi/srfi-171.scm

-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
tsegment
4242
tpartition
4343
tinterpose
44-
tindex
4544
tlog))
4645

4746
(include "171-impl.scm")

srfi/srfi-171/meta.scm

+1-73
Original file line numberDiff line numberDiff line change
@@ -27,77 +27,5 @@
2727
bytevector-u8-reduce
2828
port-reduce))
2929

30+
(include "../srfi-171-meta.scm")
3031

31-
;; A reduced value is stops the transduction.
32-
(define-record-type <reduced>
33-
(reduced val)
34-
reduced?
35-
(val unreduce))
36-
37-
38-
;; helper function which ensures x is reduced.
39-
(define (ensure-reduced x)
40-
(if (reduced? x)
41-
x
42-
(reduced x)))
43-
44-
45-
;; helper function that wraps a reduced value twice since reducing functions (like list-reduce)
46-
;; unwraps them. tconcatenate is a good example: it re-uses it's reducer on it's input using list-reduce.
47-
;; If that reduction finishes early and returns a reduced value, list-reduce would "unreduce"
48-
;; that value and try to continue the transducing process.
49-
(define (preserving-reduced reducer)
50-
(lambda (a b)
51-
(let ((return (reducer a b)))
52-
(if (reduced? return)
53-
(reduced return)
54-
return))))
55-
56-
57-
;; This is where the magic tofu is cooked
58-
(define (list-reduce f identity lst)
59-
(if (null? lst)
60-
identity
61-
(let ((v (f identity (car lst))))
62-
(if (reduced? v)
63-
(unreduce v)
64-
(list-reduce f v (cdr lst))))))
65-
66-
(define (vector-reduce f identity vec)
67-
(let ((len (vector-length vec)))
68-
(let loop ((i 0) (acc identity))
69-
(if (= i len)
70-
acc
71-
(let ((acc (f acc (vector-ref vec i))))
72-
(if (reduced? acc)
73-
(unreduce acc)
74-
(loop (+ i 1) acc)))))))
75-
76-
(define (string-reduce f identity str)
77-
(let ((len (string-length str)))
78-
(let loop ((i 0) (acc identity))
79-
(if (= i len)
80-
acc
81-
(let ((acc (f acc (string-ref str i))))
82-
(if (reduced? acc)
83-
(unreduce acc)
84-
(loop (+ i 1) acc)))))))
85-
86-
(define (bytevector-u8-reduce f identity vec)
87-
(let ((len (bytevector-length vec)))
88-
(let loop ((i 0) (acc identity))
89-
(if (= i len)
90-
acc
91-
(let ((acc (f acc (bytevector-u8-ref vec i))))
92-
(if (reduced? acc)
93-
(unreduce acc)
94-
(loop (+ i 1) acc)))))))
95-
96-
(define (port-reduce f identity reader port)
97-
(let loop ((val (reader port)) (acc identity))
98-
(if (eof-object? val)
99-
acc
100-
(let ((acc (f acc val)))
101-
(if (reduced? acc)
102-
(unreduce acc)
103-
(loop (reader port) acc))))))

tests-guile.scm

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; These are guile-specific tests. They contain guile-specific hash-tables (as are used in the reference implementation)..
2+
3+
4+
(use-modules (srfi srfi-64)
5+
(srfi srfi-171))
6+
7+
(include "tests.scm")

tests-r7rs.scm

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
;; These are guile-specific tests. They contain guile-specific hash-tables (as are used in the reference implementation)..
2+
3+
4+
(import (scheme base)
5+
(scheme char)
6+
(scheme list)
7+
(srfi 171))
8+
(cond-expand
9+
(gauche (import (only (gauche base) compose)
10+
(srfi 64)))
11+
(chibi (import (rapid test))))
12+
13+
(cond-expand
14+
(chibi (begin
15+
(define compose
16+
(lambda (f g)
17+
(lambda args
18+
(f (apply g args)))))))
19+
(else (begin)))
20+
21+
(include "tests.scm")

0 commit comments

Comments
 (0)