Skip to content

Commit

Permalink
Simplify import statements
Browse files Browse the repository at this point in the history
Removes an unnecessary level of indentation, and changes them from
using lists to expressions.

Closes hylang#1612
  • Loading branch information
vodik committed May 28, 2018
1 parent e66743c commit 364e698
Show file tree
Hide file tree
Showing 42 changed files with 178 additions and 168 deletions.
7 changes: 6 additions & 1 deletion NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ Other Breaking Changes
made into its own object type.
* `HySymbol` no longer inherits from `HyString`.
* `(except)` is no longer allowed. Use `(except [])` instead.
* `(import [foo])` is no longer allowed. Use `(import foo)` instead.
* The `import` and `require` expressions have been reworked. They now takes
arguments as expressions instead of lists

* `(import [foo])` is no longer allowed. Use `(import foo)` instead.
* `(import [foo :as bar])` is no longer allowed. Use `(import foo :as bar)`.
* `(import [foo [bar]])` is no longer allowed. Use `(import foo [bar])`.

New Features
------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/contrib/hy_repr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Hy representations
``hy.contrib.hy-repr`` is a module containing two functions.
To import them, say::

(import [hy.contrib.hy-repr [hy-repr hy-repr-register]])
(import hy.contrib.hy-repr [hy-repr hy-repr-register])

To make the Hy REPL use it for output, invoke Hy like so::

Expand Down
2 changes: 1 addition & 1 deletion docs/contrib/loop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Example:

.. code-block:: hy
(require [hy.contrib.loop [loop]])
(require hy.contrib.loop [loop])
(defn factorial [n]
(loop [[i n] [acc 1]]
Expand Down
6 changes: 3 additions & 3 deletions docs/contrib/multi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ with the arity overloaded one. Inspired by Clojures take on ``defn``.

.. code-block:: clj
=> (require [hy.contrib.multi [defn]])
=> (require hy.contrib.multi [defn])
=> (defn fun
... ([a] "a")
... ([a b] "a b")
Expand Down Expand Up @@ -43,7 +43,7 @@ on the code by `Adam Bard`_.

.. code-block:: clj
=> (require [hy.contrib.multi [defmulti defmethod default-method]])
=> (require hy.contrib.multi [defmulti defmethod default-method])
=> (defmulti area [shape]
... "calculate area of a shape"
... (:type shape))
Expand Down Expand Up @@ -91,7 +91,7 @@ different implementations can narrow them down.

.. code-block:: clj
=> (require [hy.contrib.multi [defmulti defmethod]])
=> (require hy.contrib.multi [defmulti defmethod])
=> (defmulti fun [&rest args]
... (len args))
Expand Down
4 changes: 2 additions & 2 deletions docs/contrib/profile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Example:

.. code-block:: hy
(require [hy.contrib.profile [profile/calls]])
(require hy.contrib.profile [profile/calls])
(profile/calls (print "hey there"))
Expand All @@ -42,7 +42,7 @@ Example:

.. code-block:: hy
(require [hy.contrib.profile [profile/cpu]])
(require hy.contrib.profile [profile/cpu])
(profile/cpu (print "hey there"))
.. code-block:: bash
Expand Down
4 changes: 2 additions & 2 deletions docs/contrib/sequences.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ so:

.. code-block:: hy
(require [hy.contrib.sequences [defseq seq]])
(import [hy.contrib.sequences [Sequence end-sequence]])
(require hy.contrib.sequences [defseq seq])
(import hy.contrib.sequences [Sequence end-sequence])
The simplest sequence can be defined as ``(seq [n] n)``. This defines a sequence
that starts as ``[0 1 2 3 ...]`` and continues forever. In order to define a
Expand Down
6 changes: 3 additions & 3 deletions docs/contrib/walk.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Example:

.. code-block:: hy
=> (import [hy.contrib.walk [walk]])
=> (import hy.contrib.walk [walk])
=> (setv a '(a b c d e f))
=> (walk ord identity a)
HyExpression([
Expand All @@ -47,7 +47,7 @@ each sub-form, uses ``f`` 's return value in place of the original.

.. code-block:: hy
=> (import [hy.contrib.walk [postwalk]])
=> (import hy.contrib.walk [postwalk])
=> (setv trail '([1 2 3] [4 [5 6 [7]]]))
=> (defn walking [x]
... (print "Walking:" x :sep "\n")
Expand Down Expand Up @@ -127,7 +127,7 @@ each sub-form, uses ``f`` 's return value in place of the original.

.. code-block:: hy
=> (import [hy.contrib.walk [prewalk]])
=> (import hy.contrib.walk [prewalk])
=> (setv trail '([1 2 3] [4 [5 6 [7]]]))
=> (defn walking [x]
... (print "Walking:" x :sep "\n")
Expand Down
2 changes: 1 addition & 1 deletion docs/extra/anaphoric.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concise and easy to read.

To use these macros you need to require the ``hy.extra.anaphoric`` module like so:

``(require [hy.extra.anaphoric [*]])``
``(require hy.extra.anaphoric [*])``

.. _ap-if:

Expand Down
36 changes: 18 additions & 18 deletions docs/language/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ point per form via the name instead of always the first or last argument.
'Sir Joseph Cooke Verco'
;; more convoluted example to load web page and retrieve data from it
=> (import [urllib.request [urlopen]])
=> (import urllib.request [urlopen])
=> (as-> (urlopen "http://docs.hylang.org/en/stable/") it
... (.read it)
... (.decode it "utf-8")
Expand Down Expand Up @@ -1100,29 +1100,29 @@ that ``import`` can be used.
;; Import from a module
;;
;; Python: from os.path import exists, isdir, isfile
(import [os.path [exists isdir isfile]])
(import os.path [exists isdir isfile])
;; Import with an alias
;;
;; Python: import sys as systest
(import [sys :as systest])
(import sys :as systest)
;; You can list as many imports as you like of different types.
;;
;; Python:
;; from tests.resources import kwtest, function_with_a_dash
;; from os.path import exists, isdir as is_dir, isfile as is_file
;; import sys as systest
(import [tests.resources [kwtest function-with-a-dash]]
[os.path [exists
isdir :as dir?
isfile :as file?]]
[sys :as systest])
(import tests.resources [kwtest function-with-a-dash])
os.path [exists
isdir :as dir?
isfile :as file?]
sys :as systest)
;; Import all module functions into current namespace
;;
;; Python: from sys import *
(import [sys [*]])
(import sys [*])
fn
Expand Down Expand Up @@ -1349,16 +1349,16 @@ The following are all equivalent ways to call a macro named ``foo`` in the modul
(require mymodule)
(mymodule.foo 1)
(require [mymodule :as M])
(require mymodule :as M)
(M.foo 1)
(require [mymodule [foo]])
(require mymodule [foo])
(foo 1)
(require [mymodule [*]])
(require mymodule [*])
(foo 1)
(require [mymodule [foo :as bar]])
(require mymodule [foo :as bar])
(bar 1)
Macros that call macros
Expand All @@ -1381,16 +1381,16 @@ And then, in your main program, you write:

.. code-block:: clj
(require [mymodule [foo]])
(require mymodule [foo])
(print (mymodule.foo 3))
Running this raises ``NameError: name 'repexpr' is not defined``, even though
writing ``(print (foo 3))`` in ``mymodule`` works fine. The trouble is that your
main program doesn't have the macro ``repexpr`` available, since it wasn't
imported (and imported under exactly that name, as opposed to a qualified name).
You could do ``(require [mymodule [*]])`` or ``(require [mymodule [foo
repexpr]])``, but a less error-prone approach is to change the definition of
You could do ``(require mymodule [*])`` or ``(require mymodule [foo
repexpr])``, but a less error-prone approach is to change the definition of
``foo`` to require whatever sub-macros it needs:

.. code-block:: clj
Expand All @@ -1400,8 +1400,8 @@ repexpr]])``, but a less error-prone approach is to change the definition of
(require mymodule)
(mymodule.repexpr ~n (input "Gimme some input: "))))
It's wise to use ``(require mymodule)`` here rather than ``(require [mymodule
[repexpr]])`` to avoid accidentally shadowing a function named ``repexpr`` in
It's wise to use ``(require mymodule)`` here rather than ``(require mymodule
[repexpr])`` to avoid accidentally shadowing a function named ``repexpr`` in
the main program.

Qualified macro names
Expand Down
2 changes: 1 addition & 1 deletion docs/language/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,7 @@ Returns an iterator by calling *fn* repeatedly.

.. code-block:: hy
=> (import [random [randint]])
=> (import random [randint])
=> (list (take 5 (repeatedly (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -651,15 +651,15 @@ Let's take the classic:

.. code-block:: clj
(require [hy.contrib.loop [loop]])
(require hy.contrib.loop [loop])
(loop (print (eval (read))))
Rather than write it like that, we can write it as follows:

.. code-block:: clj
(require [hy.contrib.loop [loop]])
(require hy.contrib.loop [loop])
(-> (read) (eval) (print) (loop))
Expand All @@ -669,7 +669,7 @@ a pipe:

.. code-block:: clj
=> (import [sh [cat grep wc]])
=> (import [sh cat grep wc])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))
210
Expand Down
4 changes: 2 additions & 2 deletions hy/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def ideas_macro(ETname):
return HyExpression([HySymbol('print'),
HyString(r"""
=> (import [sh [figlet]])
=> (import sh [figlet])
=> (figlet "Hi, Hy!")
_ _ _ _ _ _
| | | (_) | | | |_ _| |
Expand All @@ -173,7 +173,7 @@ def ideas_macro(ETname):
;;; this one plays with command line bits
(import [sh [cat grep]])
(import sh [cat grep])
(-> (cat "/usr/share/dict/words") (grep "-E" "bro$"))
Expand Down
44 changes: 22 additions & 22 deletions hy/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,12 @@ def imports_as_stmts(self, expr):
ret += self.compile(e)
names = sorted(name for name in names if name)
if names:
imports = [HySymbol(module)]
imports.extend(HySymbol(name) for name in names)
e = HyExpression([
HySymbol("import"),
HyList([
HySymbol(module),
HyList([HySymbol(name) for name in names])
])
HySymbol(imports[0]),
HyList(imports[1:])
]).replace(expr)
spoof_positions(e)
ret += self.compile(e)
Expand Down Expand Up @@ -1079,9 +1079,10 @@ def compile_unary_operator(self, expr, root, arg):
return operand

@special(["import", "require"], [many(
SYM |
brackets(SYM, sym(":as"), SYM) |
brackets(SYM, brackets(many(SYM + maybe(sym(":as") + SYM)))))])
SYM + maybe(
sym(":as") + SYM |
brackets(many(SYM + maybe(sym(":as") + SYM)))
))])
def compile_import_or_require(self, expr, root, entries):
"""
TODO for `require`: keep track of what we've imported in this run and
Expand All @@ -1090,28 +1091,27 @@ def compile_import_or_require(self, expr, root, entries):
"""
ret = Result()

for entry in entries:
for module, rest in entries:
assignments = "ALL"
prefix = ""

if isinstance(entry, HySymbol):
if rest is None:
# e.g., (import foo)
module, prefix = entry, entry
elif isinstance(entry, HyList) and isinstance(entry[1], HySymbol):
# e.g., (import [foo :as bar])
module, prefix = entry
prefix = module
elif isinstance(rest, HySymbol):
# e.g., (import foo :as bar)
prefix = rest
else:
# e.g., (import [foo [bar baz :as MyBaz bing]])
# or (import [foo [*]])
module, kids = entry
kids = kids[0]
if (HySymbol('*'), None) in kids:
if len(kids) != 1:
star = kids[kids.index((HySymbol('*'), None))][0]
names, = rest
# e.g., (import foo [bar baz :as MyBaz bing])
# or (import foo [*])
if (HySymbol('*'), None) in names:
if len(names) != 1:
star = names[names.index((HySymbol('*'), None))][0]
raise HyTypeError(star, "* in an import name list "
"must be on its own")
else:
assignments = [(k, v or k) for k, v in kids]
assignments = [(k, v or k) for k, v in names]

if root == HySymbol("import"):
ast_module = ast_str(module, piecewise=True)
Expand All @@ -1136,7 +1136,7 @@ def compile_import_or_require(self, expr, root, entries):
for k, v in assignments]
ret += node(
expr, module=module or None, names=names, level=level)
else: # root == HySymbol("require")
else: # root == HySymbol("require")
__import__(module)
require(module, self.module_name,
assignments=assignments, prefix=prefix)
Expand Down
2 changes: 1 addition & 1 deletion hy/contrib/botsbuildbots.hy
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"Build bots, repeatedly.^W^W^WPrint the AUTHORS, forever."
`(try
(do
(import [requests])
(import requests)

(setv r (requests.get
"https://raw.githubusercontent.com/hylang/hy/master/AUTHORS"))
Expand Down
8 changes: 4 additions & 4 deletions hy/contrib/hy_repr.hy
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
;; license. See the LICENSE.

(import
[math [isnan]]
math [isnan]
re
datetime
collections
[hy._compat [PY3 PY36 str-type bytes-type long-type]]
[hy.models [HyObject HyExpression HySymbol HyKeyword HyInteger HyFloat HyComplex HyList HyDict HySet HyString HyBytes]])
hy._compat [PY3 PY36 str-type bytes-type long-type]
hy.models [HyObject HyExpression HySymbol HyKeyword HyInteger HyFloat HyComplex HyList HyDict HySet HyString HyBytes])

(try
(import [_collections_abc [dict-keys dict-values dict-items]])
(import _collections_abc [dict-keys dict-values dict-items])
(except [ImportError]
(defclass C)
(setv [dict-keys dict-values dict-items] [C C C])))
Expand Down
Loading

0 comments on commit 364e698

Please sign in to comment.