Next: Listener, Previous: Interactive session, Up: Library modules - Gauche extensions [Contents][Index]

`gauche.lazy`

- Lazy sequence utilities- Module:
**gauche.lazy** -
This module provides utility procedures that yields lazy sequences. For the details of lazy sequences, see Lazy sequences.

Since lazy sequences are forced implicitly and indistinguishable
from ordinary lists, we don’t need a separate set of procedures
for *taking* lists and lazy sequences; we can use `find`

to search in both ordinary lists and lazy sequences.

However, we do need a separate set of procedures
for *returning* either lists or lazy sequences. For example,
`lmap` can take any kind of sequences, and
returns lazy sequence (and calls the procedure on demand).

This distinction is subtle, so I reiterate it. You can use
both `map`

and `lmap`

on lazy sequences. If you want
the result list at once, use `map`

; it doesn’t have
overhead of delayed calculation. If you don’t know you’ll use
the entire result, or you know the result will get very large
list and don’t want to waste space for an intermediate list,
you want to use `lmap`

.

- Function:
**x->lseq***obj* A convenience function to coerce

`obj`to (possibly lazy) list. If`obj`is a list, it is returned as it is. If`obj`is other type of collection, the return value is a lazy sequence that iterates over the collection.If you try

`x->lseq`

in REPL, it looks as if it just converts the input collection to a list.(x->lseq '#(a b c)) ⇒ (a b c)

But that’s because the lazy sequence is forced by the output routine of the REPL.

- Function:
**lunfold***p f g seed :optional tail-gen* A lazy version of

`unfold`

(see SRFI-1 List utilities). The arguments`p`,`f`and`g`are procedures, each of which take one argument, the current seed value. The predicate`p`determines when to stop,`f`creates each element, and`g`generates the next seed value. The`seed`argument gives the initial seed value. If`tail-gen`is given, it should also be a procedure that takes one argument, the last seed value (that is, the seed value`(p seed)`

returned`#f`

). It must return a (possibly lazy) list, that forms the tail of the resulting sequence.(lunfold ($ = 10 $) ($ * 2 $) ($ + 1 $) 0 (^_ '(end))) ⇒ (0 2 4 6 8 10 12 14 16 18 end)

- Function:
**lmap***proc seq seq2 …* Returns a lazy sequence consists of values calculated by applying

`proc`to every first element of`seq``seq2`

…, every second element of them, etc., until any of the input is exhausted.

- Function:
**lmap-accum***proc seed seq seq2 …* The procedure

`proc`takes one element each from`seq``seq2`…, plus the current seed value. It must return two values, a result value and the next seed value. The result of`lmap-accum`

is a lazy sequence consists of the first values returned by each invocation of`proc`.This is a lazy version of

`map-accum`

(see Mapping over collection), but`lmap-accum`

does not return the final seed value. We only know the final seed value when we have the result sequence to the end, so it can’t be calculated lazily.

- Function:
**lappend***seq …* Returns a lazy sequence consists of elements in

`seq`….

- Function:
**lconcatenate***seqs* The

`seqs`argument is a sequence of sequences. Returns a lazy sequence that is a concatenation of all the sequences in`seqs`.This differs from

`(apply lappend seqs)`

, for`lconcatenate`

can handle infinite number of lazy`seqs`.

- Function:
**lappend-map***proc seq1 seq …* Lazy version of

`append-map`

. This differs not only from`(apply lappend (lmap proc seq1 seq …))`

, which would evaluate the result of`lmap`

to the end before passing it to`lappend`

, but also differ from`(lconcatenate (lmap proc seq1 seq …))`

in the subtle way.Remember that Gauche’s lazy sequence evaluates one element ahead?

`lconcatenate`

does that to the result of`lmap`

. To see the effect, let’s define a procedure with a debug print:(define (p x) #?=(list x x))

You can see that

`(apply lappend (lmap ...))`

wouldn’t delay any of application of`p`

:gosh> (car (apply lappend (lmap p '(1 2 3)))) (car (apply lappend (lmap p '(1 2 3)))) #?="(standard input)":4:(list x x) #?- (1 1) #?="(standard input)":4:(list x x) #?- (2 2) #?="(standard input)":4:(list x x) #?- (3 3) 1

How about

`lconcatenate`

?gosh> (car (lconcatenate (lmap p '(1 2 3)))) (car (lconcatenate (lmap p '(1 2 3)))) #?="(standard input)":4:(list x x) #?- (1 1) #?="(standard input)":4:(list x x) #?- (2 2) 1

Oops, even though we need only the first element, and the first result of

`lmap`

,`(1 1)`

, provides the second element, too,`p`

is already applied to the second input.This is because the intermediate lazy list of the result of

`lmap`

is evaluated “one element ahead”. On the other hand,`lappend-map`

doesn’t have this problem.gosh> (car (lappend-map p '(1 2 3))) (car (lappend-map p '(1 2 3))) #?="(standard input)":4:(list x x) #?- (1 1) 1

- Function:
**linterweave***seq …* Returns a lazy seq of the first items from

`seq`…, then their second items, and so on. If the length of shortest sequence of`seqs`is N, the length of the resulting sequence is`(* N number-of-sequences)`

. If all of`seq`s are infinite, the resulting sequence is also infinite.(linterweave (lrange 0) '(a b c d e) (circular-list '*)) ⇒ (0 a * 1 b * 2 c * 3 d * 4 e *)

- Function:
**lfilter***proc seq* Returns a lazy sequence that consists of non-false values calculated by applying

`proc`on every elements in`seq`.

- Function:
**lfilter-map***proc seq seq2 …* Lazy version of

`filter-map`

.

- Function:
**lstate-filter***proc seed seq* Lazy version of

`gstate-filter`

.

- Function:
**ltake***seq n :optional fill? padding* - Function:
**ltake-while***pred seq* Lazy versions of

`take*`

and`take-while`

(see List accessors and modifiers). Note that`ltake`

works rather like`take*`

than`take`

, that is, it won’t complain if the input sequence has less than`n`elements. Because of the lazy nature of`ltake`

, it can’t know whether input is too short or not before returning the sequence.There are no

`ldrop`

and`ldrop-while`

; if you apply`drop`

and`drop-while`

on lazy sequence, they return lazy sequence.

- Function:
**lrxmatch***rx seq* This is a lazy sequence version of

`grxmatch`

(see Generator operations).The

`seq`argument must be a sequence of characters. The return value is a lazy sequence of`<rxmatch>`objects, each representing strings matching to the regular expression`rx`.This procedure is convenient to scan character sequences from lazy character sequences, but it may be slow if you’re looking for rarely matching string from very large input. Unless

`seq`is a string,`lrxmatch`

buffers certain

- Function:
**lslices***seq k :optional fill? padding* Lazy version of

`slices`

(see List accessors and modifiers).(lslices '(a b c d e f) 2) ⇒ ((a b) (c d) (e f))