* 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
