================ Anaphoric Macros ================ .. versionadded:: 0.9.12 The anaphoric macros module makes functional programming in Hy very concise and easy to read. An anaphoric macro is a type of programming macro that deliberately captures some form supplied to the macro which may be referred to by an anaphor (an expression referring to another). -- Wikipedia (https://en.wikipedia.org/wiki/Anaphoric_macro) To use these macros you need to require the ``hy.extra.anaphoric`` module like so: ``(require [hy.extra.anaphoric [*]])`` These macros are implemented by replacing any use of the designated anaphoric symbols (``it``, in most cases) with a gensym. Consequently, it's unwise to nest these macros where symbol replacement is happening. Symbol replacement typically takes place in ``body`` or ``form`` parameters, where the output of the expression may be returned. It is also recommended to avoid using an affected symbol as something other than a variable name, as in ``(print "My favorite Stephen King book is" 'it)``. .. _ap-if: ap-if ===== Usage: ``(ap-if test-form then-form else-form)`` As :ref:`if `, but the result of the test form is named ``it`` in the subsequent forms. As with ``if``, the else-clause is optional. .. code-block:: hy => (import os) => (ap-if (.get os.environ "PYTHONPATH") ... (print "Your PYTHONPATH is" it)) .. _ap-each: ap-each ======= Usage: ``(ap-each xs body…)`` Evaluate the body forms for each element ``it`` of ``xs`` and return ``None``. .. code-block:: hy => (ap-each [1 2 3] (print it)) 1 2 3 .. _ap-each-while: ap-each-while ============= Usage: ``(ap-each-while xs pred body…)`` As ``ap-each``, but the form ``pred`` is run before the body forms on each iteration, and the loop ends if ``pred`` is false. .. code-block:: hy => (ap-each-while [1 2 3 4 5 6] (< it 4) (print it)) 1 2 3 .. _ap-map: ap-map ====== Usage: ``(ap-map form xs)`` Create a generator like :py:func:`map` that yields each result of ``form`` evaluated with ``it`` bound to successive elements of ``xs``. .. code-block:: hy => (list (ap-map (* it 2) [1 2 3])) [2, 4, 6] .. _ap-map-when: ap-map-when =========== Usage: ``(ap-map-when predfn rep xs)`` As ``ap-map``, but the predicate function ``predfn`` (yes, that's a function, not an anaphoric form) is applied to each ``it``, and the anaphoric mapping form ``rep`` is only applied if the predicate is true. Otherwise, ``it`` is yielded unchanged. .. code-block:: hy => (list (ap-map-when odd? (* it 2) [1 2 3 4])) [2, 2, 6, 4] => (list (ap-map-when even? (* it 2) [1 2 3 4])) [1, 4, 3, 8] .. _ap-filter: ap-filter ========= Usage: ``(ap-filter form xs)`` The :py:func:`filter` equivalent of ``ap-map``. .. code-block:: hy => (list (ap-filter (> (* it 2) 6) [1 2 3 4 5])) [4, 5] .. _ap-reject: ap-reject ========= Usage: ``(ap-reject form xs)`` Equivalent to ``(ap-filter (not form) xs)``. .. code-block:: hy => (list (ap-reject (> (* it 2) 6) [1 2 3 4 5])) [1, 2, 3] .. _ap-dotimes: ap-dotimes ========== Usage: ``(ap-dotimes n body…)`` Equivalent to ``(ap-each (range n) body…)``. .. code-block:: hy => (setv n []) => (ap-dotimes 3 (.append n it)) => n [0, 1, 2] .. _ap-first: ap-first ======== Usage: ``(ap-first form xs)`` Evaluate the predicate ``form`` for each element ``it`` of ``xs``. When the predicate is true, stop and return ``it``. If the predicate is never true, return ``None``. .. code-block:: hy => (ap-first (> it 5) (range 10)) 6 .. _ap-last: ap-last ======== Usage: ``(ap-last form list)`` Evaluate the predicate ``form`` for every element ``it`` of ``xs``. Return the last element for which the predicate is true, or ``None`` if there is no such element. .. code-block:: hy => (ap-last (> it 5) (range 10)) 9 .. _ap-reduce: ap-reduce ========= Usage: ``(ap-reduce form xs &optional initial-value)`` This macro is an anaphoric version of :py:func:`reduce`. It works as follows: - Bind ``acc`` to the first element of ``xs``, bind ``it`` to the second, and evaluate ``form``. - Bind ``acc`` to the result, bind ``it`` to the third value of ``xs``, and evaluate ``form`` again. - Bind ``acc`` to the result, and continue until ``xs`` is exhausted. If ``initial-value`` is supplied, the process instead begins with ``acc`` set to ``initial-value`` and ``it`` set to the first element of ``xs``. .. code-block:: hy => (ap-reduce (+ it acc) (range 10)) 45 .. _#% #% == Usage: ``#% expr`` Makes an expression into a function with an implicit ``%`` parameter list. A ``%i`` symbol designates the (1-based) *i* th parameter (such as ``%3``). Only the maximum ``%i`` determines the number of ``%i`` parameters--the others need not appear in the expression. ``%*`` and ``%**`` name the ``&rest`` and ``&kwargs`` parameters, respectively. .. code-block:: hy => (#%[%1 %6 42 [%2 %3] %* %4] 1 2 3 4 555 6 7 8) [1, 6, 42, [2, 3], (7, 8), 4] => (#% %** :foo 2) {"foo": 2} When used on an s-expression, ``#%`` is similar to Clojure's anonymous function literals--``#()``. .. code-block:: hy => (setv add-10 #%(+ 10 %1)) => (add-10 6) 16 ``#%`` determines the parameter list by the presence of a ``%*`` or ``%**`` symbol and by the maximum ``%i`` symbol found *anywhere* in the expression, so nesting of ``#%`` forms is not recommended.