[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] sequences egg
Re: [Chicken-users] sequences egg
Fri, 19 Nov 2010 07:00:49 -0700
On Fri, Nov 19, 2010 at 03:20:42AM -0500, Felix wrote:
> From: Alan Post <address@hidden>
> Subject: Re: [Chicken-users] sequences egg
> Date: Thu, 18 Nov 2010 08:37:35 -0700
> > On Thu, Nov 18, 2010 at 10:03:44AM -0500, Felix wrote:
> >> Hello!
> >> I've put together a little library of generic "sequence" operations,
> >> and would like to get some feedback, since I'm not sure about the
> >> nomenclature and API. Find it here:
> >> http://wiki.call-cc.org/eggref/4/sequences
> >> And in the repo, usual place. It has a test-suite, but surely contains
> >> some bugs, and is a bit of a test for the "fast-generic" extension.
> >> Comments, suggestions, rants or critique is welcome.
> >> (I think it needs a very recent chicken, but am not quite sure,
> >> it may work with older versions)
> > When I write programs with iterators, I find myself using:
> > map
> > zip/unzip
> > chain
> > remove/filter
> > nearly every time. I use:
> > tee (copy)
> > pairwise
> > count
> > repeat
> Could you provide examples for `chain', `pairwise' and `repeat'?
Chain is like append, it takes a list of sequences and returns all
of sequence 1, all of sequence 2, &c.
I use chain when my data comes from different sources (say two
separate files) but I can treat it as a single stream.
pairwise could be (now that #!optional handling is fixed!):
(define (pairwise a #!optional (b (cdr a)))
(if (null? (cdr b))
`((,(car a) ,(car b)))
(cons `(,(car a) ,(car b)) (pairwise (cdr a) (cdr b)))))
(test '((a b) (b c) (c d)) (pairwise '(a b c d)))
I have used pairwise when I have a file I need to break into smaller
pieces, I'll take the size of the file, divide it into chunks, say
1000 lines, and then use pairwise to generate my boundaries:
(pairwise (0 1000 2000 2256))
So each unit processing a portion of the file gets a start (inclusive)
and end (exclusive) boundary.
I'll also us it when I need to assert some condition about my data,
say that each number is greater than the number before it in a
repeat acts like circular-list from srfi-1:
(repeat 'a) => (a a a ...)
(repeat '(a b c)) => (a b c a b c ...)
or is that last one?:
(repeat 'a 'b 'c) => (a b c a b c ...)
I use repeat along with zip to append information to a stream that
I'll later modify, say if I'm deciling a bunch of data, I'll provide
a default decile of 0 with repeat before performing the calculation.
> > One thing I notice missing is that you have linear-sequence and
> > random-access-sequence, but what about something like a pipe, which
> > is a linear-sequence with (say) the additional constraint of only
> > being able to traverse it once? Similarly, if you had a routine
> > like repeat, it is a linear-sequence that is non-finite.
> Good points. How would you express that operationally?
pipe I would say acts like a dynamic variable. Any reference to the
iterator operates on the same stream, and once the iteration is
exhausted it can't be used again. If pairwise worked, it would
((a b) (c d))
because the separate references to |a| and |b| are using the same
non-finite sequences only make sense to me when paired with a finite
sequence using zip. The idea is that the shortest sequence in a set
causes iteration to step for all other sequences in that set:
(zip '(foo bar baz)
'(1 2 3 4)
=> (foo 1 a) (bar 2 a) (baz 3 a)
.i ko djuno fi le do sevzi