sequencestanza

Empty sequence when looping on a sequence for the second time


In stanza, I would like to loop two times over a sequence.

I have something like that:

public defn function1-and-function2 (s:Seqable<Double>) -> [Double, Double]:
   [function1(s), function2(s)]

with

public defn function1 (s:Seqable<Double>) -> Double

and

public defn function2 (s:Seqable<Shape>) -> Double

In both function1 and function2, I am looping on the sequence. But when reaching function2, the sequence is empty.


Solution

  • A Seqable is a lazily calculated sequence of values, and in general, you are only allowed to iterate through it once.

    Thus, the general solution is to first store all of the values (e.g. in a tuple) and then you can pass this tuple to each of your functions:

    val t = to-tuple(s)
    [function1(t), function2(t)]
    

    However, for your particular case, it is obvious that function1 and function2 can be calculated independently of each other. So it is possible to iterate through the sequence once, and then concurrently calculate the result of both function1 and function2. There is a fancy function in core called fork-on-seq that lets you do this:

    fork-on-seq(s, function1, function2)