14fddbe6c3
Give `require` the same features as `import` You can now do (require foo), (require [foo [a b c]]), (require [foo [*]]), and (require [foo :as bar]). The first and last forms get you macros named foo.a, foo.b, etc. or bar.a, bar.b, etc., respectively. The second form only gets the macros in the list. Implements #1118 and perhaps partly addresses #277. N.B. The new meaning of (require foo) will cause all existing code that uses macros to break. Simply replace these forms with (require [foo [*]]) to get your code working again. There's a bit of a hack involved in the forms (require foo) or (require [foo :as bar]). When you call (foo.a ...) or (bar.a ...), Hy doesn't actually look inside modules. Instead, these (require ...) forms give the macros names that have periods in them, which happens to work fine with the way Hy finds and interprets macro calls. * Make `require` syntax stricter and add tests * Update documentation for `require` * Documentation wording improvements * Allow :as in `require` name lists
57 lines
1.8 KiB
ReStructuredText
57 lines
1.8 KiB
ReStructuredText
==========
|
|
loop/recur
|
|
==========
|
|
|
|
.. versionadded:: 0.10.0
|
|
|
|
The ``loop`` / ``recur`` macro gives programmers a simple way to use
|
|
tail-call optimization (TCO) in their Hy code.
|
|
|
|
A tail call is a subroutine call that happens inside another
|
|
procedure as its final action; it may produce a return value which
|
|
is then immediately returned by the calling procedure. If any call
|
|
that a subroutine performs, such that it might eventually lead to
|
|
this same subroutine being called again down the call chain, is in
|
|
tail position, such a subroutine is said to be tail-recursive,
|
|
which is a special case of recursion. Tail calls are significant
|
|
because they can be implemented without adding a new stack frame
|
|
to the call stack. Most of the frame of the current procedure is
|
|
not needed any more, and it can be replaced by the frame of the
|
|
tail call. The program can then jump to the called
|
|
subroutine. Producing such code instead of a standard call
|
|
sequence is called tail call elimination, or tail call
|
|
optimization. Tail call elimination allows procedure calls in tail
|
|
position to be implemented as efficiently as goto statements, thus
|
|
allowing efficient structured programming.
|
|
|
|
-- Wikipedia (https://en.wikipedia.org/wiki/Tail_call)
|
|
|
|
Macros
|
|
======
|
|
|
|
.. _loop:
|
|
|
|
loop
|
|
-----
|
|
|
|
``loop`` establishes a recursion point. With ``loop``, ``recur``
|
|
rebinds the variables set in the recursion point and sends code
|
|
execution back to that recursion point. If ``recur`` is used in a
|
|
non-tail position, an exception is raised.
|
|
|
|
Usage: ``(loop bindings &rest body)``
|
|
|
|
Example:
|
|
|
|
.. code-block:: hy
|
|
|
|
(require [hy.contrib.loop [loop]])
|
|
|
|
(defn factorial [n]
|
|
(loop [[i n] [acc 1]]
|
|
(if (zero? i)
|
|
acc
|
|
(recur (dec i) (* acc i)))))
|
|
|
|
(factorial 1000)
|