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
>
>

Reply via email to