diff --git a/docs/api.rst b/docs/api.rst index d2c878cf2..29fa9c5bd 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -339,58 +339,49 @@ base names, such that ``hy.core.macros.foo`` can be called as just ``foo``. .. hy:macro:: (for [#* args]) - ``for`` compiles to one or more :py:keyword:`for` statements, which - execute code repeatedly for each element of an iterable object. - The return values of the forms are discarded and the ``for`` form - returns ``None``. + ``for`` compiles to one or more :py:keyword:`for` statements, which execute + code repeatedly for each element of an iterable object. The return values of + the forms are discarded and the ``for`` form returns ``None``. :: - :: - - => (for [x [1 2 3]] - ... (print "iterating") - ... (print x)) - iterating - 1 - iterating - 2 - iterating - 3 + (for [x [1 2 3]] + (print "iterating") + (print x)) + ; Output: iterating 1 iterating 2 iterating 3 - The first argument of ``for``, in square brackets, specifies how to loop. A simple and common case is ``[variable values]``, where ``values`` is a form that evaluates to an iterable object (such as a list) and ``variable`` is a symbol specifiying the name to assign each element to. Subsequent arguments to ``for`` are body forms to be evaluated for each iteration of the loop. + The first argument of ``for``, in square brackets, specifies how to loop. A + simple and common case is ``[variable values]``, where ``values`` is a form + that evaluates to an iterable object (such as a list) and ``variable`` is a + symbol specifiying the name for each element. Subsequent arguments to ``for`` + are body forms to be evaluated for each iteration of the loop. More generally, the first argument of ``for`` allows the same types of clauses as :hy:func:`lfor`:: - => (for [x [1 2 3] :if (!= x 2) y [7 8]] - ... (print x y)) - 1 7 - 1 8 - 3 7 - 3 8 - - The last argument of ``for`` can be an ``(else …)`` form. - This form is executed after the last iteration of the ``for``\'s - outermost iteration clause, but only if that outermost loop terminates - normally. If it's jumped out of with e.g. ``break``, the ``else`` is - ignored. - - :: - - => (for [element [1 2 3]] (if (< element 3) - ... (print element) - ... (break)) - ... (else (print "loop finished"))) - 1 - 2 - - => (for [element [1 2 3]] (if (< element 4) - ... (print element) - ... (break)) - ... (else (print "loop finished"))) - 1 - 2 - 3 - loop finished + (for [x [1 2 3] :if (!= x 2) y [7 8]] + (print x y)) + ; Output: 1 7 1 8 3 7 3 8 + + In particular, you can use an ``:async`` clause to get the equivalent of + Python's :py:keyword:`async for`:: + + (import asyncio) + (defn/a numbers [] + (yield 1) + (yield 2)) + (asyncio.run ((fn/a [] + (for [:async x (numbers)] + (print x))))) + + The last argument of ``for`` can be an ``(else …)`` form. This form is + executed after the last iteration of the ``for``\'s outermost iteration + clause, but only if that outermost loop terminates normally. If it's jumped + out of with e.g. ``break``, the ``else`` is ignored. :: + + (for [x [1 2 3]] + (print x) + (when (= x 2) + (break)) + (else (print "loop finished"))) .. hy:macro:: (assert [condition [label None]])