On Apr 2, Sam TH wrote: > > Here's the implementation of `cycle' (which should probably be in the > sequence library): > [...]
Below is a better implementation of `in-sequences' using a `append-sequences' helper. It's also implementing `in-cycle', which just uses the same `append-sequences' utility with a cyclic list of the inputs. (And BTW, it doesn't cache the items, which looks like a mistake to do.) After that I implemented an `in-lazy' macro, using `in-thunk' (with apologies for Ryan...) -- the cute thing is that you can then implement a cyclic iteration with: (for ([i (letrec ([seq (in-sequences (in-range 4) (in-lazy seq))]) seq)]) (printf "i = ~s\n" i)) or even: (for ([i (letrec ([seq (in-lazy (in-sequences (in-range 4) seq))]) seq)]) (printf "i = ~s\n" i)) But there's a problem with this -- AFAICT, there is no way for a sequence to just return a new sequence to iterate over, which would be a tail-call kind of transfer to the new sequence. So the `in-lazy' thing must create a sequence that forever wraps the input sequence. The result is a growing chain of sequence proxies. Maybe there's a nice way to extend the api so a sequence can stop and return a "continuation sequence", but looking at the code that change doesn't look easy. In any case, I don't think that there are any practical uses of an `in-lazy', so it looks to my like `in-sequences' and `in-cycle' are enough as an addtion. #lang scheme (define (append-sequences seqs) (define (seqs->m+g+r seqs) (and (pair? seqs) (let-values ([(more? get) (sequence-generate (car seqs))]) (list* more? get (cdr seqs))))) (make-do-sequence (lambda () ;; place is (cur-more? cur-get rest-seqs ...) or #f (values (lambda (m+g+r) ((cadr m+g+r))) (lambda (m+g+r) (let loop ([m+g+r m+g+r]) (if (and (pair? m+g+r) (not ((car m+g+r)))) (seqs->m+g+r (cddr m+g+r)) m+g+r))) (seqs->m+g+r seqs) (lambda (p) p) (lambda _ #t) (lambda _ #t))))) (define (in-sequences . seqs) (append-sequences seqs)) (define (in-cycle . seqs) (append-sequences (shared ([x (append seqs x)]) x))) (define (in-thunk sthunk) (make-do-sequence (lambda () (define-values [more? get] (sequence-generate (sthunk))) (values (lambda (_) (get)) void (void) (lambda (_) (more?)) (lambda _ #t) (lambda _ #t))))) (define-syntax-rule (in-lazy seq-expr) (in-thunk (lambda () seq-expr))) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://www.barzilay.org/ Maze is Life! _________________________________________________ For list-related administrative tasks: http://list.cs.brown.edu/mailman/listinfo/plt-dev