hy/docs/language/core.rst
Bob Tolbert 62f1f40830 Add set of new core functions
Add set of new core functions to the stdlib.

Moved the auto-import code from compile_expression to
HySymbol so that "even?' in this style expression will
be found and imported.

(list (filter even? [1 2 3 4 5]))

The core functions are documented in 2 sections, one
for basic functions like (even?..) and (nth ...) and
one for all the sequence functions.

Update: This removes all the caching decorators, misnamed as
'lazy-seq' from the core. All sequence methods now just use
yield to return a generator, so they are Python-lazy

Further refinements of core functions

Cleaned up the docs to use 'iterator' instead of 'generator'

Fixed drop to just return the iterator instead of an extra
yield loop. But also added a test to catch dropping too
many.
2013-07-13 09:55:16 -06:00

553 lines
7.9 KiB
ReStructuredText

=================
Hy Core
=================
Core Functions
===============
.. _dec-fn:
dec
---
Usage: ``(dec x)``
Return one less than x. Equivalent to ``(- x 1)``.
.. code-block:: clojure
=> (dec 3)
2
=> (dec 0)
-1
=> (dec 12.3)
11.3
.. _even?-fn:
even?
-----
Usage: ``(even? x)``
Return True if x is even.
.. code-block:: clojure
=> (even? 2)
True
=> (even? 13)
False
=> (even? 0)
True
.. _inc-fn:
inc
---
Usage: ``(inc x)``
Return one more than x. Equivalent to ``(+ x 1)``.
.. code-block:: clojure
=> (inc 3)
4
=> (inc 0)
1
=> (inc 12.3)
13.3
.. _instance?-fn:
instance?
---------
Usage: ``(instance? CLASS x)``
Return True if x is an instance of CLASS.
.. code-block:: clojure
=> (instance? float 1.0)
True
=> (instance? int 7)
True
=> (instance? str (str "foo"))
True
=> (defclass TestClass [object])
=> (setv inst (TestClass))
=> (instance? TestClass inst)
True
.. _iterable?-fn:
iterable?
---------
Usage: ``(iterable? x)``
Return True if x is iterable. Iterable objects return a new iterator
when ``(iter x)`` is called. Contrast with :ref:`iterator?-fn`.
.. code-block:: clojure
=> ;; works for strings
=> (iterable? (str "abcde"))
True
=> ;; works for lists
=> (iterable? [1 2 3 4 5])
True
=> ;; works for tuples
=> (iterable? (, 1 2 3))
True
=> ;; works for dicts
=> (iterable? {:a 1 :b 2 :c 3})
True
=> ;; works for iterators/generators
=> (iterable? (repeat 3))
True
.. _iterator?-fn:
iterator?
---------
Usage: ``(iterator? x)``
Return True if x is an iterator. Iterators are objects that return
themselves as an iterator when ``(iter x)`` is called.
Contrast with :ref:`iterable?-fn`.
.. code-block:: clojure
=> ;; doesn't work for a list
=> (iterator? [1 2 3 4 5])
False
=> ;; but we can get an iter from the list
=> (iterator? (iter [1 2 3 4 5]))
True
=> ;; doesn't work for dict
=> (iterator? {:a 1 :b 2 :c 3})
False
=> ;; create an iterator from the dict
=> (iterator? (iter {:a 1 :b 2 :c 3}))
True
.. _neg?-fn:
neg?
----
Usage: ``(neg? x)``
Return True if x is less than zero (0).
.. code-block:: clojure
=> (neg? -2)
True
=> (neg? 3)
False
=> (neg? 0)
False
.. _none?-fn:
none?
-----
Usage: ``(none? x)``
Return True if x is None.
.. code-block:: clojure
=> (none? None)
True
=> (none? 0)
False
=> (setf x None)
=> (none? x)
True
=> ;; list.append always returns None
=> (none? (.append [1 2 3] 4))
True
.. _nth-fn:
nth
---
Usage: ``(nth coll n)``
Return the `nth` item in a collection, counting from 0. Unlike
``get``, ``nth`` works on both iterators and iterables. Returns ``None``
if the `n` is outside the range of `coll`.
.. code-block:: clojure
=> (nth [1 2 4 7] 1)
2
=> (nth [1 2 4 7] 3)
7
=> (none? (nth [1 2 4 7] 5))
True
=> (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))
5
.. _odd?-fn:
odd?
----
Usage: ``(odd? x)``
Return True if x is odd.
.. code-block:: clojure
=> (odd? 13)
True
=> (odd? 2)
False
=> (odd? 0)
False
.. _pos?-fn:
pos?
----
Usage: ``(pos? x)``
Return True if x is greater than zero (0).
.. code-block:: clojure
=> (pos? 3)
True
=> (pos? -2)
False
=> (pos? 0)
False
Sequence Functions
=======================
Sequence functions can either create or operate on a potentially
infinite sequence without requiring the sequence be fully realized in
a list or similar container. They do this by returning a Python
iterator.
We can use the canonical infinite Fibonacci number generator
as an example of how to use some of these functions.
.. code-block:: clojure
(defn fib []
(setf a 0)
(setf b 1)
(while true
(yield a)
(setf (, a b) (, b (+ a b)))))
Note the ``(while true ...)`` loop. If we run this in the REPL,
.. code-block:: clojure
=> (fib)
<generator object fib at 0x101e642d0>
Calling the function only returns an iterator, but does no
work until we consume it. Trying something like this is not recommend as
the infinite loop will run until it consumes all available RAM, or
in this case until I killed it.
.. code-block:: clojure
=> (list (fib))
[1] 91474 killed hy
To get the first 10 Fibonacci numbers, use :ref:`take-fn`. Note that
:ref:`take-fn` also returns a generator, so I create a list from it.
.. code-block:: clojure
=> (list (take 10 (fib)))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
To get the Fibonacci number at index 9, (starting from 0):
.. code-block:: clojure
=> (nth (fib) 9)
34
.. _cycle-fn:
cycle
------
Usage: ``(cycle coll)``
Return an infinite iterator of the members of coll.
.. code-block:: clj
=> (list (take 7 (cycle [1 2 3])))
[1, 2, 3, 1, 2, 3, 1]
=> (list (take 2 (cycle [1 2 3])))
[1, 2]
.. _distinct-fn:
distinct
--------
Usage: ``(distinct coll)``
Returns an iterator containing only the unique members in ``coll``.
.. code-block:: clojure
=> (list (distinct [ 1 2 3 4 3 5 2 ]))
[1, 2, 3, 4, 5]
=> (list (distinct []))
[]
=> (list (distinct (iter [ 1 2 3 4 3 5 2 ])))
[1, 2, 3, 4, 5]
.. _drop-fn:
drop
----
Usage: ``(drop n coll)``
Return an iterator, skipping the first ``n`` members of ``coll``
.. code-block:: clojure
=> (list (drop 2 [1 2 3 4 5]))
[3, 4, 5]
=> (list (drop 4 [1 2 3 4 5]))
[5]
=> (list (drop 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]
=> (list (drop 6 [1 2 3 4 5]))
[]
.. _filter-fn:
filter
------
Usage: ``(filter pred coll)``
Return an iterator for all items in ``coll`` that pass the predicate ``pred``.
See also :ref:`remove-fn`.
.. code-block:: clojure
=> (list (filter pos? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]
=> (list (filter even? [1 2 3 -4 5 -7]))
[2, -4]
.. _iterate-fn:
iterate
-------
Usage: ``(iterate fn x)``
Return an iterator of `x`, `fn(x)`, `fn(fn(x))`.
.. code-block:: clojure
=> (list (take 5 (iterate inc 5)))
[5, 6, 7, 8, 9]
=> (list (take 5 (iterate (fn [x] (* x x)) 5)))
[5, 25, 625, 390625, 152587890625]
.. _remove-fn:
remove
------
Usage: ``(remove pred coll)``
Return an iterator from ``coll`` with elements that pass the
predicate, ``pred``, removed.
See also :ref:`filter-fn`.
.. code-block:: clojure
=> (list (remove odd? [1 2 3 4 5 6 7]))
[2, 4, 6]
=> (list (remove pos? [1 2 3 4 5 6 7]))
[]
=> (list (remove neg? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]
.. _repeat-fn:
repeat
------
Usage: ``(repeat x)``
Return an iterator (infinite) of ``x``.
.. code-block:: clojure
=> (list (take 6 (repeat "s")))
[u's', u's', u's', u's', u's', u's']
.. _repeatedly-fn:
repeatedly
----------
Usage: ``(repeatedly fn)``
Return an iterator by calling ``fn`` repeatedly.
.. code-block:: clojure
=> (import [random [randint]])
=> (list (take 5 (repeatedly (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]
.. _take-fn:
take
----
Usage: ``(take n coll)``
Return an iterator containing the first ``n`` members of ``coll``.
.. code-block:: clojure
=> (list (take 3 [1 2 3 4 5]))
[1, 2, 3]
=> (list (take 4 (repeat "s")))
[u's', u's', u's', u's']
=> (list (take 0 (repeat "s")))
[]
.. _take-nth-fn:
take-nth
--------
Usage: ``(take-nth n coll)``
Return an iterator containing every ``nth`` member of ``coll``.
.. code-block:: clojure
=> (list (take-nth 2 [1 2 3 4 5 6 7]))
[1, 3, 5, 7]
=> (list (take-nth 3 [1 2 3 4 5 6 7]))
[1, 4, 7]
=> (list (take-nth 4 [1 2 3 4 5 6 7]))
[1, 5]
=> (list (take-nth 10 [1 2 3 4 5 6 7]))
[1]
.. _take-while-fn:
take-while
----------
Usage: ``(take-while pred coll)``
Return an iterator from ``coll`` as long as predicate, ``pred`` returns True.
.. code-block:: clojure
=> (list (take-while pos? [ 1 2 3 -4 5]))
[1, 2, 3]
=> (list (take-while neg? [ -4 -3 1 2 5]))
[-4, -3]
=> (list (take-while neg? [ 1 2 3 -4 5]))
[]