[racket-dev] `stream-map', again (Add multiple streams and a contract to stream-map)

From: Eli Barzilay (eli at barzilay.org)
Date: Fri Nov 2 15:19:48 EDT 2012

Yesterday, Diogo F. S. Ramos wrote:
> Adding multiple streams feature to stream-map makes it more in line
> with its list counterpart.  [...]

The code in your patch had several problems, so I started re-hacking
it, yet again.  I obviously wrote a macro so I can knock out
`stream-for-each', `stream-andmap', and `stream-ormap' too.  I did the
mistake of actually looking at the code after I wrote the macro, so
only then I saw that the other functions actually call out to the
sequence versions, which themselves could use the same kind of
generalization, but those are also spread over two files (some in
racket/private/sequence), and they're implemented in different ways.
If anyone wants to take that, and FWIW, the macro is below.

Also, there are the folding functions.

[As a side-note, it's unfortunate that there are so many versions of
practically the same thing, for lists, sequences, streams, lazy
racket, etc.]



(define-syntax-rule (define-mapper name combine)
  (define name
    (case-lambda
      [(f s)
       (unless (and (procedure? f)
                    (procedure-arity-includes? f 1))
         (raise-argument-error 'name "procedure of arity 1" f))
       (unless (stream? s) (raise-argument-error 'name "stream?" s))
       (let loop ([s s])
         (if (-stream-empty? s)
           empty-stream
           (combine (f (-stream-first s)) (loop (-stream-rest s)))))]
      [(f s . ss)
       (define streams (cons s ss))
       (unless (and (procedure? f)
                    (procedure-arity-includes? f (length streams)))
         (raise-argument-error
          'name
          (format "procedure of arity ~s" (length streams)) f))
       (for ([s (in-list streams)])
         (unless (stream? s) (raise-argument-error 'name "stream?" s)))
       (let loop ([streams streams])
         (if (ormap -stream-empty? streams)
           empty-stream
           (combine (apply f (map -stream-first s))
                    (loop (map -stream-rest s)))))])))

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.