From: Helmut Eller <heller@co...>  20100726 06:19:22

* Raymond Toy [20100726 02:13+0200] writes: > On 7/23/10 12:25 PM, Helmut Eller wrote: >> * Raymond Toy [20100723 15:00+0200] writes: >> >>> On 7/23/10 4:15 AM, Helmut Eller wrote: >>>> Hello, >>>> >>>> I'd like to create a macro/function that when given two series >>>> as input produces the "cross product" as output. E.g. >>>> >>>> (cross (scan '(a b c)) (scan '(1 2 3))) >>>> => #Z(a a a b b b c c c) and #Z(1 2 3 1 2 3 1 2 3) >>>> >>> Do the two series have the same length? >> Yes, the output series have the same length (possibly infinite). > Sorry, I'm still confused. If the series have infinite length, then the > first series from cross will repeat the first element forever? Or > something else? Yes, it's repeated. [But in a lazy fashion, so that the version with ITERATE wouldn't work if the client only consumes the first 10 elements.] >> >>> I'm a bit confused on exactly what cross should do. >> Another way to write CROSS would be: >> >> (defmacro cross (sx sy) >> `(let ((xs '()) (ys '())) >> (iterate ((x ,sx)) >> (iterate ((y ,sy)) >> (push x xs) >> (push y ys))) >> (values (scan (reverse xs)) >> (scan (reverse ys))))) >> >> Obviously inefficient, but hopefully clearer. > This produces something different from the original cross. I get > > (cross (scan '(a b c)) (scan '(1 2 3))) > > #Z(a a a b b b c c c) > #z(1 2 3 1 2 3 1 2 3) That's the same as what I quoted above, no? >> One series expression drives the outer loop and the other series >> expression drives the inner loop. The outer loop produces a series; >> lets call that #z(x_0 x_1 ... x_n). The inner loop consumes that >> series. For each element x_i the inner loop produces (part of) a series >> #z(y_i_0 y_i_1 ... y_i_m) and additionally copies x_i m times to a > What is the value of m? In the example it's 3; #z(y_i_0 y_i_1 ... y_i_m) corresponds to one of the #z(1 2 3) segments. > How is it derived from the inputs? I realize now that the second argument of cross can't be a just a series it must be a function that produces a series (the current element of the first series is passed in as argument). It's that function that decides how long the segments get. > I think it's ok if the output of a series function is "faster" than the > inputs. The function SPREAD produces more output data than the input > data series. Yes, that looks promising. I'm trying to write some examples here http://projectfortress.sun.com/Projects/Community/wiki/ComprehendingComprehensions with series. They enumerate Pythagorean Triples with generator expressions. It feels like that should be possible with series too, but actually doing it is quite hard. Helmut 