81 lines
2.2 KiB
ReStructuredText
81 lines
2.2 KiB
ReStructuredText
==============
|
|
Lazy sequences
|
|
==============
|
|
|
|
.. versionadded:: 0.12.0
|
|
|
|
The 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 the element multiple times. Since they
|
|
cache calculated values, they aren't suited for infinite sequences. However,
|
|
the implementation allows for 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]])
|
|
|
|
The 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 the 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 the amount of items in the sequence and negative indexing is supported.
|
|
Because both of thse require evaluating the whole sequence, calling such a
|
|
function would take forever (or at least until available memory has been
|
|
exhausted).
|
|
|
|
Sequences can be defined recursively. The 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 the 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``.
|