============== Lazy sequences ============== .. versionadded:: 0.12.0 Sequences module contains few macros for declaring sequences that are evaluated only as much as the client code requests elements. Compared to generators they allow accessing same element multiple times. Since they cache calculated values, they aren't suited for infinite sequences. However, the implementation allows recursive definition of sequences, without resulting recursive computation. To use these macros you need to require them and import other types like: .. code-block:: hy (require [hy.contrib.sequences [defseq seq]]) (import [hy.contrib.sequences [Sequence end-sequence]]) Simplest sequence can be defined as: ``(seq [n] n)``. This defines a sequence that starts as: ``[0 1 2 3 ...]`` and continues forever. In order to define a finite sequence, ``end-sequence`` needs to be called to signal end of the sequence: .. code-block:: hy (seq [n] "sequence of 5 integers" (cond [(< n 5) n] [true (end-sequence)])) This creates following sequence: ``[0 1 2 3 4]``. For such a sequence ``len`` returns amount of items in sequence and negative indexing is suported. Because both of thse require evaluating whole sequence, calling such a function would take forever (or at least until available memory has been exhausted). Sequence can be defined recursively. Canonical example of fibonacci numbers is defined as: .. code-block:: hy (defseq fibonacci [n] "infinite sequence of fibonacci numbers" (cond [(= n 0) 0] [(= n 1) 1] [true (+ (get fibonacci (- n 1)) (get fibonacci (- n 2)))])) This results sequence of ``[0 1 1 2 3 5 8 13 21 34 ...]``. .. _seq: seq === Usage: ``(seq [n] (* n n)`` Creates a sequence defined in terms of ``n``. .. _defseq: defseq ====== Usage: ``(defseq numbers [n] n)`` Creates a sequence defined in terms of ``n`` and assigns it to a given name. .. _end-sequence: end-sequence ============ Usage: ``(seq [n] (if (< n 5) n (end-sequence)))`` Signals end of a sequence when iterator reaches certain point of sequence. Internally this is done by raising ``IndexError``, catching that in iterator and raising ``StopIteration``.