Chris,
since you're asking similar questions in series-users and iterate-devel, I'm starting to wonder whether you're going to write a paper on comparisons of some looping frameworks? :-)
how do I go about collecting the last N elements of anything? (iter (for line :in-file my-file :using #'read-line) (collect-tail line :how-many 10))
If 10 is known at macro-expansion time, you can always write a macro that expands to a series of 10 uses of PREVIOUS in Iterate, or 10 consecutive latches in Series.
I.e., IMHO there are always two ways, either with series of iterate:
a) Either take a code generation approach and create code that latches (= delay by one) N times,
b) Or take a functional approach, implement a ring datastructure and use that.
The former looks like a better use of Series: it could be a series of the 10 last values (as a list, or 10 series of values farther and farther behind).
In/After the last iteration, you'll have the 10 last values.
As to which approach is better... Probably you wouldn't want to generate code for the last 100 values.
BTW, you'll have to defined what happens when less than 10 iterations were taken. Straight-forward code is likely to return (val1 val2 nil nil ...6xnil), whereas one could wish for (val1 val2) with only 2 iterations.
Regards, Jorg Hohle.
"Hoehle, Joerg-Cyril" Joerg-Cyril.Hoehle@t-systems.com writes:
a) Either take a code generation approach and create code that latches (= delay by one) N times,
b) Or take a functional approach, implement a ring datastructure and use that.
Thanks for the great advice.
This is the same reasoning I used. I have since implemented collect-tail and series-tail using a ring and I will say that it was more straight forward to write collect-tail for the iterate system.
since you're asking similar questions in series-users and iterate-devel,
This is my standard looping question in any language: Read the last N lines of a file, transform them, filter them, and return the unique elements. This is a nice test because (to use Series lingo I didn't know until recently) it combines on-line and off-line processing.
I'm starting to wonder whether you're going to write a paper on comparisons of some looping frameworks? :-)
:-)
Some papers one might wish to read are the recent Shivers paper [1] and the Egner paper [2]. They provide a decent overview from a Scheme perspective.
These papers don't really go into the use of iterators/generators ala Python, Ruby, and CLU. (This is the approach where one uses yield in the generator to return control to the loop.) It's too bad they don't delve into iterators because it is a very elegant approach to the problem (albeit with some performance hurdles).
It would be an interesting problem to write a performant iterator system in Common Lisp.
Thanks again, Chris Dean
Footnotes:
[1] The anatomy of a loop: a story of scope and control. Olin Shivers. http://www.cc.gatech.edu/~shivers/citations.html#loop
[2] Eager Comprehensions in Scheme: The design of SRFI-42 Sebastian Egner http://www.deinprogramm.de/scheme-2005/program.html