Eduardo, Isn't 5 functions too much for iterable protocol ?
I have made a similar library which can iterate over almost everything. The protocol has only 1 function: next, returning unique end-of-sequnce simbol. Code is here https://code.google.com/p/scheme-snippets/source/browse/trunk/iter.ss Sorry for alpha quality and bad comments, it is a bit abandoned. Anyway, despite of so simple protocol, the library is feature-rich and useful. I use it often when write in scheme, adding new functions and implementing TODO on demand. On Wed, Feb 17, 2010 at 12:12 AM, Eduardo Cavazos <[email protected]>wrote: > Hello, > > Ports and lists are "iterable". Vectors, strings, and bytevectors are > "mutable indexable". > > Import my 'define-record-type++': > > (import (dharmalab records define-record-type)) > > Define the "iterable" protocol: > > (define-record-type++ iterable-protocol > (fields iterator empty? next rest new-from-list)) > > Define 'for-each' functor over the iterable protocol: > > (define (make-iterable-for-each protocol) > > (import-iterable-protocol protocol) > > (define (for-each col f) > (let loop ((iter (iterator col))) > (when (not (empty? iter)) > (f (next iter)) > (loop (rest iter))))) > > for-each) > > Define the iterable protocol for lists: > > (define iterable-protocol/list > (make-iterable-protocol (lambda (x) x) > null? > car > cdr > (lambda (x) x))) > > Define list-for-each: > > (define list-for-each > (make-iterable-for-each iterable-protocol/list)) > > Define the iterable protocol for input-ports: > > (define iterable-protocol/input-port > (make-iterable-protocol (lambda (x) x) > (lambda (p) > (eof-object? > (lookahead-char p))) > lookahead-char > (lambda (p) > (get-char p) > p) > #f)) > > Define input-port-for-each: > > (define input-port-for-each > (make-iterable-for-each iterable-protocol/input-port)) > > Now let's switch over to the mutable indexable protocol. > > Define it: > > (define-record-type++ mutable-indexable-protocol > (fields new-of-length size ref put copy)) > > Define the 'for-each' functor over the mutable-indexable protocol: > > (define (make-mutable-indexable-for-each protocol) > > (import-mutable-indexable-protocol protocol) > > (define (for-each seq proc) > (let ((n (size seq))) > (let loop ((i 0)) > (when (< i n) > (proc (ref seq i)) > (loop (+ i 1)))))) > > for-each) > > Define the mutable-indexable-protocol for vectors: > > (define mutable-indexable-protocol/vector > (make-mutable-indexable-protocol make-vector > vector-length > vector-ref > vector-set! > vector-copy-into! > )) > > Define vector-for-each: > > (define vector-for-each > (make-mutable-indexable-for-each mutable-indexable-protocol/vector)) > > Define the mutable-indexable-protocol for strings: > > (define mutable-indexable-protocol/string > (make-mutable-indexable-protocol make-string > string-length > string-ref > string-set! > string-copy-into! > )) > > Define string-for-each: > > (define string-for-each > (make-mutable-indexable-for-each mutable-indexable-protocol/string)) > > Similar for bytevectors. > > The benefit is that you define 'for-each' once for each protocol and all > implementors of the protocol get it "for free". > > If anybody knows of previous work in this area for Scheme, let me know. > > Also, I'd like to hear folks's opinion on this issue... > > It's possible to have vectors be "iterable" by having an iterator > interface over them. One drawback is that the iterator abstraction adds > some overhead; there is no layer of abstraction involved with the > "mutable indexable" protocol. If performance is a priority, a separate > protocol seems the way to go. > > Ed > >
