(sagittarius generators) - Generators

Library (sagittarius generators)

This library provides procedures for generator.

A generator is simply a procedure with no arguments that works as a source of a series of values. Every time it is called, it yields a value. Generators may be finite or infinite; a finite generator returns an EOF object to indicate that it is exhausted. For example, read-char is a generator that generates characters from the current input port. Generators provide lightweight laziness.

Generator constructors

The following procedures creates a generator. Except null-generator, all procedures have prefix 'g'. Arguments named _generator_indicates a generator.

Returns a generator which always returns EOF object.

Returns a generator which repeats the given _obj_s.

Returns a generator which returns count number of numbers. The returning numbers start with start and increased by step.

(generator->list (giota 5))
(0 1 2 3 4)

(generator->list (giota 5 10))
(10 11 12 13 14)

(generator->list (giota 5 10 2))
(10 12 14 16 18)

If count is not given, then the generator is inifinte.

Returns a generator which returns numbers in range of start and end. The returning numbers are increased by step.

A generator constructor similar to unfold.

(generator->list (gunfold
                      (lambda (s) (> s 5))
                      (lambda (s) (* s 2))
                      (lambda (s) (+ s 1))
                      0))
(0 2 4 6 8 10)

Generator constructors. The returning generator returns the items taken from given argument from the beginning of the given sequence to the end. Except reverse-vector->generator which return end to beginning.

Generator constructors. The returning generator returns the items read from the given port. The port->char-generator uses get-charto read the port. The port->byte-generator uses get-u8.

Generic constructor of generators. By default, the following methods are defined and dispatched above generator constrocturs.

<list>, <vector>, <string>, <bytevector> and <port>.

If the given argument is type of <vector>, then vector->generatoris used. If the given argument is type of <port>, then it checks if it's binary or textual and dispatches apropriate procedure.

Generator operations

Returns a generator which adds _object_s in front of generator.

Returns a generator which yields values from the first _generator_and when it's exhausted continues to next.

Returns a generator for mapping with state. It yields a sequence of sub-folds over proc.

The proc argument is a procedure which takes as many arguments as the input generators plus one. It is called as (_proc_ _v1_ _v2_ ... _seed_), where v1, v2,... are the values yielded from the input generators, and seed is the current seed value. It must return two values, the yielding value and the next seed.

Return generators which yield the items from the source generator, except those on which pred returns false or true respectively.

Return generators which take or drop k items from generator, respectively. Returning generators won't raise errors when it's exhausted before reaching k.

Optional argument padding for gtake is passed, then the value is filled until the procedure reaches k.

These procedures are analogues of SRFI-1 take and drop.

Return generators which take or drop until procedure pred returns false value respectively.

These procedures are analogues of SRFI-1 take-while and drop-while.

Returns a generator which returns items generator returns, except items which are the same as item in sense of =.

Returns a generator which returns items generator returns, except items which are the same as the proceeding item in sense of =.

Returns a generator which returns the items generated by value-generator of specified by the indice generated by index-generator. The indice must be non negative integer and increased strictly. Otherwise an error is raised.

(generator->list (gindex (list->generator '(a b c d e f))
                 (list->generator '(0 2 4))))
(a c e)

Returns a generator which returns the items generated by value-generator that correspond to the items generated by truth-generator. If truth-generator returns true value, then the current value of value-generator is returned. Otherwise not.

(generator->list (gselect (list->generator '(a b c d e f))
                          (list->generator '(#t #f #f #t #t #f))))
(a d e)

generator must be an generator generates generators.

Returns a generator which returns the items generated by the generators generated by given generator. It is similar to the following:

(apply gappend (generator->list generator))

The difference is that this procedure can handle infinite generator.

generator must be a generator which returns lists as its items.

Returns a generator which flatten the items generated by given generator.

(generator->list (gflatten (list->generator (list '(1 2 3 4)
                                                  '(a b c d)
                                                  '(A B C D)))))
(1 2 3 4 a b c d A B C D)

If the generator returns non list item, then it is ignored.

(generator->list (gflatten (list->generator (list 'ignored
                                                  '(a b c d)
                                                  'ignored
                                                  '(A B C D)))))
(a b c d A B C D)

This behaviour is an error behaviour so it might be changed in future. So users should not depend on this.

compare must be a procedure which accepts 2 arguments and returns boolean value. The procedure should compare the given 2 arguments and return true value if the first argument is smaller than the second argument.

Returns a generator which returns the ordered items determined by _compare_procedure. If the gmerge procedure is called only one argument, then it simply returns a generator (if generator1 isn't a generator then it is coerced).

(generator->list (gmerge < (list->generator '(1 4 5)) (list->generator '(0 2 3))))
(0 1 2 3 4 5)

Returns a generator which returns the items returned by proc.

The proc is called with the items returned by generator1 and generator2 if it's given.

The gmap procedure accepts uneven length of generators however one of the generator must be finite length, otherwise it won't be exhausted.

It is an analogy of map.

Returns a generator which returns the items returnd by proc.

This procedure is similar with gmap. The difference is that the returning item is filtered if the returning value of proc is #f.

It is an analogy of filter-map.

Returns a coroutine generator which return the item returned by proc.

The given argument proc must accept one argument, yield which is a procedure accepts variable arguments. The proc procedure can return values via yield procedure.

(define g
  (make-coroutine-generator
    (lambda (yield) 
      (let loop ((i 0))
        (when (< i 3) 
          (yield i) 
          (loop (+ i 1)))))))

(generator->list g)
(0 1 2)

glet* is a macro which is similar to let*. The difference is that glet* check if the bindings are EOF object or not and if it detects EOF object, then it returns EOF object immediately.

bindings must be one of the following forms:

If the first form is used, then the gen-expr is bound to var. Otherwise the glet* just check if the value is EOF or not.

(define g (list->generator '(1 2 3)))

(list 
  (glet* ((a (g))) a)
  (glet* ((a (g))) (define b 2) (+ a b))
  (glet* ((a (g)) (b (g))) (+ a b)))
(1 2 #\<eof>)

Convenient macro for only one binding of glet*. This is defined like the following:

(define-syntax glet1
  (syntax-rules ()
    ((_ var expr body body1 ...)
     (glet* ((var expr)) body body1 ...))))

Iterates generator of then given gen-expr.