Michael Heerdegen writes: >> I don't have a quick answer for the general case, but I think it's a bug >> in stream.el that it's creating such large structures in the first >> place. As far as I understand it, the point of streams is to handle >> long lists by encoding them as >> >> (FIRST-VALUE . FUNCTION-TO-PRODUCE-REST-OF-LIST) > > Yes, that's exactly how it's implemented. When requesting more elements > from the stream, that becomes > > (FIRST-VALUE . > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST)) > > When we loop over the string, the cons whose car is the FIRST-VALUE, > let's call it cons1, is immediately thrown away, and we continue with > > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST) Coming back to this again. I think I got lost in the weeds of the byte-code function objects before. The core problem is that streams are not exactly encoded like the above, because even after forcing it you don't have just a plain SECOND-VALUE stored in the stream. The original FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST stays around and keeps referencing all the code and all the following elements. So a possible solution is change the stream to get rid of the lambda part and just leave the computed value after it's forced. With the following patch (stream-flush (stream-range 1 1000000)) succeeds: