Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import syntax improvements #1612

Closed
vodik opened this issue May 20, 2018 · 9 comments · Fixed by #2107
Closed

import syntax improvements #1612

vodik opened this issue May 20, 2018 · 9 comments · Fixed by #2107

Comments

@vodik
Copy link
Contributor

vodik commented May 20, 2018

We've used to have three forms for importing:

(import foo)          ; import foo
(import [foo])        ; import foo
(import [foo [bar]])  ; from foo import bar

We've currently dropped the second form, but that leaves a weird inconsistency:

(import foo)          ; import foo
(import [foo [bar]])  ; from foo import bar

The inner list is no longer necessary. We're now free to change the syntax to be less nested:

(import foo)          ; import foo
(import [foo bar])    ; from foo import bar

And this is close to how Clojure does it (though with expressions instead of lists):

(import (java.util Date Calendar)
        (java.net URI ServerSocket)
        java.sql.DriverManager)
@gilch
Copy link
Member

gilch commented May 20, 2018

If you drop the inner list like that, I think we should switch to () like Clojure. Semantically, () means the head is special, and it's highlighted as such, while the tail has the arguments, while [] means either the elements are equal status or it contains assignment pairs. I think we used nested [] before because this assignment hint holds for many of Hy's forms, with setv as a notable exception. But what's weird about import is the assignment targets are on the right, which breaks the [] pattern anyway.

@gilch
Copy link
Member

gilch commented May 20, 2018

We should also make require consistent with import if we change it.

@Kodiologist
Copy link
Member

Fortunately, that's easy now that import and require are parsed with the same code.

@gilch
Copy link
Member

gilch commented May 20, 2018

Clojure's approach could perhaps be simplified further, like

(import
  bacon
  (foo.bar
    (baz quux norlf)
    spam
    eggs))

Which would be like

import bacon
from foo.bar.baz import quux, norlf
from foo.bar import spam, eggs

So an expression sets the prefix for all of its children.

But this potentially breaks the "preferably only one obvious way to do it" rule, since you can now use either a . or a new expression.

(import
  bacon
  (foo
    (bar
      (baz quux norlf)
      spam
      eggs)))

Removing the . separator is an option. We could even nest in more () to replace the . prefix for relative imports. But for common, simple cases, it gets ugly.

;; from .foo.bar.baz import quux
(import [.foo.bar.baz [quux]])  ; old way
(import (.foo.bar.baz quux))  ; proposed
(import ((foo (bar (baz quux)))))  ; no dots. How bad?

Maybe it's not worth the trouble. Clojure's way is closer to the Python compilation and it's not too hard to build macros on top of simpler special forms.

@gilch
Copy link
Member

gilch commented May 20, 2018

Related #851.

vodik added a commit to vodik/hy that referenced this issue May 21, 2018
Removes an unnecessary level of indentation, and changes them from
using lists to expressions.

Closes hylang#1612
@vodik
Copy link
Contributor Author

vodik commented May 21, 2018

I just did the basic implementation for now.

But this potentially breaks the "preferably only one obvious way to do it" rule, since you can now use either a . or a new expression

It might not be worth it as Python doesn't typically tend to have deeply nested namespaces - its instead tends to being broad.

Removing the . separator is an option. We could even nest in more () to replace the . prefix for relative imports. But for common, simple cases, it gets ugly.

Not a bad idea, but I think I see two problems:

Multiple dots are valid as a indicator to go up. Now I guess you can just toss in more parenthesis, but the question is how clearly indent level is that conveyed:

(import [...foo.bar [baz]])
(import (...foo.bar baz))
(import ((((foo (bar (baz)))))))  ; Much harder to understand at a glance

The other problem is I have no idea how you'd express this:

(import [... [foo]])  ; translates to `from ... import foo`
(import (... foo))

@gilch
Copy link
Member

gilch commented May 22, 2018

Python doesn't typically tend to have deeply nested namespaces

A good point. Even though I wished Clojure had something like this, it's probably not worth the trouble in Hy.

@Kodiologist
Copy link
Member

org.python.lang.python.util.time.dates.datetime.dateime.now.AbstractHandlerFactoryManagerFactoryDecoratorProxy

@gilch
Copy link
Member

gilch commented May 22, 2018

;; Clojure-like
(import (os.path exists
                 isdir :as dir?
                 isfile :as file?)
        sys :as systest
        re)
from os.path import exists, isdir as is_dir, isfile :as is_file
import sys as systest
import re

The closest we could get to Python would be with two special forms, import and from.

;; Python-like
(from os.path :import exists isdir :as dir? isfile :as file?)
(import sys :as systest)
(import re)

If we reverse the order, we don't need the from form. A keyword will do.

(import exists isdir :as dir? isfile :as file? :from os.path)

These have no internal brackets, but like Python, you'll need to repeat import.

vodik added a commit to vodik/hy that referenced this issue May 27, 2018
Removes an unnecessary level of indentation, and changes them from
using lists to expressions.

Closes hylang#1612
vodik added a commit to vodik/hy that referenced this issue May 28, 2018
Removes an unnecessary level of indentation, and changes them from
using lists to expressions.

Closes hylang#1612
vodik added a commit to vodik/hy that referenced this issue May 28, 2018
Removes an unnecessary level of indentation, and changes them from
using lists to expressions.

Closes hylang#1612
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants