hy/docs/contrib/sequences.rst

81 lines
2.2 KiB
ReStructuredText
Raw Normal View History

2016-11-08 05:28:12 +01:00
==============
Lazy sequences
==============
.. versionadded:: 0.12.0
2016-11-30 23:22:42 +01:00
The Sequences module contains few macros for declaring sequences that are
evaluated only as much as the client code requests elements. Compared to
2016-12-08 01:04:59 +01:00
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
2016-11-30 23:22:42 +01:00
resulting recursive computation.
2016-11-08 05:28:12 +01:00
2016-11-30 23:22:42 +01:00
To use these macros, you need to require them and import other types like:
2016-11-08 05:28:12 +01:00
.. code-block:: hy
(require [hy.contrib.sequences [defseq seq]])
(import [hy.contrib.sequences [Sequence end-sequence]])
2016-11-30 23:22:42 +01:00
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
2016-12-08 01:04:59 +01:00
define a finite sequence, ``end-sequence`` needs to be called to signal the end
2016-11-30 23:22:42 +01:00
of the sequence:
2016-11-08 05:28:12 +01:00
.. code-block:: hy
(seq [n]
"sequence of 5 integers"
2016-11-08 05:28:12 +01:00
(cond [(< n 5) n]
[true (end-sequence)]))
2016-11-30 23:22:42 +01:00
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.
2016-12-08 01:04:59 +01:00
Because both of thse require evaluating the whole sequence, calling such a
function would take forever (or at least until available memory has been
2016-11-30 23:22:42 +01:00
exhausted).
2016-11-08 05:28:12 +01:00
2016-11-30 23:22:42 +01:00
Sequences can be defined recursively. The canonical example of fibonacci numbers
2016-11-08 05:28:12 +01:00
is defined as:
.. code-block:: hy
(defseq fibonacci [n]
"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)))]))
2016-11-30 23:22:42 +01:00
This results the sequence of ``[0 1 1 2 3 5 8 13 21 34 ...]``.
2016-11-08 05:28:12 +01:00
.. _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``.