Skip to content

Commit

Permalink
Merge pull request #1325 from Kodiologist/unpacking
Browse files Browse the repository at this point in the history
Replace `apply` with unpacking operators
  • Loading branch information
kirbyfan64 committed Jul 20, 2017
2 parents c3c7af2 + 3f3cce8 commit 35f7dd3
Show file tree
Hide file tree
Showing 23 changed files with 261 additions and 261 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Changes from 0.13.0

[ Language Changes ]
* `yield-from` is no longer supported under Python 2
* `apply` has been replaced with Python-style unpacking operators `#*` and
`#**` (e.g., `(f #* args #** kwargs)`)
* Single-character "sharp macros" changed to "tag macros", which can have
longer names
* Periods are no longer allowed in keywords
Expand Down
5 changes: 3 additions & 2 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import _pytest
import hy
from hy._compat import PY3
from hy._compat import PY3, PY35

def pytest_collect_file(parent, path):
if (path.ext == ".hy"
and "/tests/native_tests/" in path.dirname + "/"
and path.basename != "__init__.hy"
and not ("py3_only" in path.basename and not PY3)):
and not ("py3_only" in path.basename and not PY3)
and not ("py35_only" in path.basename and not PY35)):
m = _pytest.python.pytest_pycollect_makemodule(path, parent)
# Spoof the module name to avoid hitting an assertion in pytest.
m.name = m.name[:-len(".hy")] + ".py"
Expand Down
96 changes: 52 additions & 44 deletions docs/language/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,41 +154,6 @@ it appends it as the last argument. The following code demonstrates this:
5 10
apply
-----

``apply`` is used to apply an optional list of arguments and an
optional dictionary of kwargs to a function. The symbol mangling
transformations will be applied to all keys in the dictionary of
kwargs, provided the dictionary and its keys are defined in-place.

Usage: ``(apply fn-name [args] [kwargs])``

Examples:

.. code-block:: clj
(defn thunk []
"hy there")
(apply thunk)
;=> "hy there"
(defn total-purchase [price amount &optional [fees 1.05] [vat 1.1]]
(* price amount fees vat))
(apply total-purchase [10 15])
;=> 173.25
(apply total-purchase [10 15] {"vat" 1.05})
;=> 165.375
(apply total-purchase [] {"price" 10 "amount" 15 "vat" 1.05})
;=> 165.375
(apply total-purchase [] {:price 10 :amount 15 :vat 1.05})
;=> 165.375
and
---

Expand Down Expand Up @@ -596,8 +561,8 @@ Parameters may have the following keywords in front of them:
parameter_1 1
parameter_2 2
; to avoid the mangling of '-' to '_', use apply:
=> (apply print-parameters [] {"parameter-1" 1 "parameter-2" 2})
; to avoid the mangling of '-' to '_', use unpacking:
=> (print-parameters #** {"parameter-1" 1 "parameter-2" 2})
parameter-1 1
parameter-2 2
Expand Down Expand Up @@ -634,19 +599,19 @@ Parameters may have the following keywords in front of them:

.. code-block:: clj
=> (defn compare [a b &kwonly keyfn [reverse false]]
=> (defn compare [a b &kwonly keyfn [reverse False]]
... (setv result (keyfn a b))
... (if (not reverse)
... result
... (- result)))
=> (apply compare ["lisp" "python"]
... {"keyfn" (fn [x y]
... (reduce - (map (fn [s] (ord (first s))) [x y])))})
=> (compare "lisp" "python"
... :keyfn (fn [x y]
... (reduce - (map (fn [s] (ord (first s))) [x y]))))
-4
=> (apply compare ["lisp" "python"]
... {"keyfn" (fn [x y]
=> (compare "lisp" "python"
... :keyfn (fn [x y]
... (reduce - (map (fn [s] (ord (first s))) [x y])))
... "reverse" True})
... :reverse True)
4
.. code-block:: python
Expand Down Expand Up @@ -1576,6 +1541,49 @@ the given conditional is ``False``. The following shows the expansion of this ma
(do statement))
unpack-iterable, unpack-mapping
-------------------------------

``unpack-iterable`` and ``unpack-mapping`` allow an iterable or mapping
object (respectively) to provide positional or keywords arguments
(respectively) to a function.

.. code-block:: clj
=> (defn f [a b c d] [a b c d])
=> (f (unpack-iterable [1 2]) (unpack-mapping {"c" 3 "d" 4}))
[1, 2, 3, 4]
``unpack-iterable`` is usually written with the shorthand ``#*``, and
``unpack-mapping`` with ``#**``.

.. code-block:: clj
=> (f #* [1 2] #** {"c" 3 "d" 4})
[1, 2, 3, 4]
With Python 3, you can unpack in an assignment list (:pep:`3132`).

.. code-block:: clj
=> (setv [a #* b c] [1 2 3 4 5])
=> [a b c]
[1, [2, 3, 4], 5]
With Python 3.5 or greater, unpacking is allowed in more contexts than just
function calls, and you can unpack more than once in the same expression
(:pep:`448`).

.. code-block:: clj
=> [#* [1 2] #* [3 4]]
[1, 2, 3, 4]
=> {#** {1 2} #** {3 4}}
{1: 2, 3: 4}
=> (f #* [1] #* [2] #** {"c" 3} #** {"d" 4})
[1, 2, 3, 4]
unquote
-------

Expand Down
4 changes: 2 additions & 2 deletions docs/language/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1216,9 +1216,9 @@ if *from-file* ends before a complete expression can be parsed.
=> (import io)
=> (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (apply read [] {"from_file" buffer}))
=> (eval (read :from_file buffer))
4
=> (eval (apply read [] {"from_file" buffer}))
=> (eval (read :from_file buffer))
1
=> ; assuming "example.hy" contains:
Expand Down
19 changes: 5 additions & 14 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -423,30 +423,21 @@ The same thing in Hy::
=> (optional-arg 1 2 3 4)
[1 2 3 4]

If you're running a version of Hy past 0.10.1 (eg, git master),
there's also a nice new keyword argument syntax::
You can call keyword arguments like this::

=> (optional-arg :keyword1 1
... :pos2 2
... :pos1 3
... :keyword2 4)
[3, 2, 1, 4]

Otherwise, you can always use `apply`. But what's `apply`?

Are you familiar with passing in `*args` and `**kwargs` in Python?::

>>> args = [1 2]
>>> kwargs = {"keyword2": 3
... "keyword1": 4}
>>> optional_arg(*args, **kwargs)

We can reproduce this with `apply`::
You can unpack arguments with the syntax ``#* args`` and ``#** kwargs``,
similar to `*args` and `**kwargs` in Python::

=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... "keyword1" 4})
=> (apply optional-arg args kwargs)
=> (optional-arg #* args #** kwargs)
[1, 2, 4, 3]

There's also a dictionary-style keyword arguments construction that
Expand All @@ -460,7 +451,7 @@ looks like:
The difference here is that since it's a dictionary, you can't rely on
any specific ordering to the arguments.

Hy also supports ``*args`` and ``**kwargs``. In Python::
Hy also supports ``*args`` and ``**kwargs`` in parameter lists. In Python::

def some_func(foo, bar, *args, **kwargs):
import pprint
Expand Down
Loading

0 comments on commit 35f7dd3

Please sign in to comment.