2016-11-08 05:28:12 +01:00
|
|
|
==============
|
|
|
|
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]
|
2016-11-09 07:52:18 +01:00
|
|
|
"sequence of 5 integers"
|
2016-11-08 05:28:12 +01:00
|
|
|
(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]
|
2016-11-09 07:52:18 +01:00
|
|
|
"infinite sequence of fibonacci numbers"
|
2016-11-08 05:28:12 +01:00
|
|
|
(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``.
|