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

Replace use id = path; with use path as id; #169

Merged
merged 3 commits into from
Aug 12, 2014

Conversation

pnkfelix
Copy link
Member

Summary: Change the rebinding syntax from use ID = PATH to use PATH as ID, so that paths all line up on the left side, and imported identifers are all on the right side. Also modify extern crate syntax
analogously, for consistency.

Rendered view

@netvl
Copy link

netvl commented Jul 16, 2014

Alternative syntax (which I find more natural) is to use fat arrow:

use a::{b => c, d => e};

Such syntax is used in Scala:

import java.util.{List => JList}

In Scala it does require boundaries (that is, curly braces) around it, but this restriction may be lifted off in Rust when there is only one identifier imported:

use a::b::c => d;

@huonw
Copy link
Member

huonw commented Jul 16, 2014

A general comment: this syntax seems like it would generalise to multiple renamings (that is, pub use foo::{bar as x, baz as y};) better than the current =; of course, there is no current plan/RFC for adding this feature so it shouldn't necessarily be given much weight in the consideration of this one.

I did a quick survey of how one aliases imports in a variety of (popularish) languages, just to try to gauge if any form has overwhelming support outside Rust (spoilers: no):

  • no renaming support: C, Java, Swift(?), F#(?)
  • path as new_name: Python, Haskell, PHP, Clojure
  • new_name = path: C++, C#, Visual Basic
  • other: Scala (module.path.{symbol => new_name}), Go (import ( new_name "package/name" )), Perl (a variety but seems to mainly be path => new_name)

@SiegeLord
Copy link

I am generally in favor of this minor adjustment, but with the caveat that this should also then be done for extern crate. I.e. extern crate "foo bar" as foo_bar; for consistency.

Go ahead with switch, so imported identifier is on the left-hand side,
but use a different token than `as` to signal a rebinding.

For example, we could use `@`, as an analogy with its use as a binding
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… except for the minor matter that the binding operator in match expressions has the identifier on the left, not the right. (Yeah, this has always struck me as back-to-front and I wonder whether we should swap it.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB. this is taken directly from Haskell's as patterns, including the current binding order.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s what I had understood. I still think it should probably be changed. (Or even replace @ with =, then the order would make sense.) Anyway, that’s outside the scope of this issue.

@chris-morgan
Copy link
Member

I am strongly in favour of this, including @SiegeLord’s addendum. It makes our syntax around this stuff closer to Python’s, also, which is in my opinion good.

@renato-zannon
Copy link

Another data point in the survey: ES6 modules have the syntaxes import "module_name" as bar, import { foo as bar } from "module_name" and module foo from "bar"

@glaebhoerl
Copy link
Contributor

I think I like this, along with @huonw's idea of generalizing it to use foo::{bar as x, baz as y}; later on. Unless there's some kind of grammatical difficulty, we could also go on to change binding in patterns to follow the same form (PAT as NAME instead of NAME@PAT), which I think would be nice.

@pczarn
Copy link

pczarn commented Jul 16, 2014

There is a grammatical difficulty in patterns related to identifiers and types. Casting 123 as num is not the same as 123 @ num. Unless we disambiguate by forbidding some exprs or PAT as IDENT in patterns. By the way, '@' means 'at'.

@glaebhoerl
Copy link
Contributor

@pczarn I'm afraid I don't completely understand. as would have a different meaning in patterns versus expressions, which is a downside that will be acutely felt by people who dislike overloading the meanings of keywords (it doesn't personally bother me nearly as much), but that's not a grammatical issue, so I assume it's not what you're referring to.

Casting 123 as num is not the same as 123 @ num.

I tried a few different ways, and could not get THING as TYPE inside a pattern to parse. Unless there's something I forgot to try, given that FOO as BAR in patterns is not currently legal, where would introducing it lead to ambiguity?

Unless we disambiguate by forbidding some exprs or PAT as IDENT in patterns.

I was not aware of expressions being currently allowed in patterns at all. I think they're not, but feel free to correct me. And patterns are precisely where PAT as IDENT would be made legal, so the idea of adding it to patterns and then forbidding it in patterns is bewildering.

(I suspect there must be something very basic which I'm missing or misunderstanding.)

@nightpool
Copy link

Much more in favor of the "as" syntax then the => or @ syntax. as is used by a large subset of functional/dynamic languages, the others look weird and are used by less languages. I also think adding the "as" will help balance out the currently symbol heavy import lines.

@pczarn
Copy link

pczarn commented Jul 16, 2014

@glaebhoerl, my mistake, it's not a grammatical issue. But consider the following shadowing:

match 1234 {
    int @ 1234 => int,
    _ => 0
}

It gets much worse when the meaning of as is overloaded:

match 1234 {
    1234 as int => int,
    _ => 0
}

@glaebhoerl
Copy link
Contributor

@pczarn I think naming your variables int is already liable to be confusing, and a thing to avoid. :) But while this change is something that might (or might not) be a natural progression from @pnkfelix's proposal, it's not strictly part of it, so we should probably reserve further discussion on it for if/when someone submits actually submits a proposal for it, to avoid cluttering the discussion on this one.

@arcto
Copy link

arcto commented Jul 16, 2014

+1 very neat. Good points:

  • makes code easier/faster to scan
  • familiarity (Haskell, Python, ...)

@pnkfelix
Copy link
Member Author

@SiegeLord I agree, it seems reasonable to apply the same change to the extern crate rebinding syntax. I will incorporate that into the RFC.

@liigo
Copy link
Contributor

liigo commented Jul 17, 2014

a big +1, i like this! thank you.

For the current syntax, use a = b;, it's not obvious which one (a or b?) is the original name, and which one is the new name. But in proposed syntax, use a as b;, it's obvious that, b is the new name, and a is the original one. Straightforward wins.

@Valloric
Copy link

This sounds nice. It's a small but worthy increase in usability.

@blaenk
Copy link
Contributor

blaenk commented Jul 17, 2014

I wholeheartedly agree with @liigo that this change would make it much more intuitive as to which name is the original. +1

@Kimundi
Copy link
Member

Kimundi commented Jul 31, 2014

+1 as well, use path::foo as bar reads better and nicer compared to use bar = path::foo.
I'm also in favor of making it consistent with extern crate: In my opinion this would result in a nice and consistent syntax:

use path::old_name;
use path::old_name as new_name;

extern crate old_name;
extern crate old_name as new_name; // Support ident case for simple renaming
extern crate "old_name" as new_name; // Support string case for arbitrary library name

Given the choice between as, @ and : I think as fits better due to other import syntax already being based on keywords.

I also think whether or not a use is pub should not change the syntax, or the semantic for that matter. Having a single module path aliasing construct and a visibility modifier it can be combined with is easier than having two different module path aliasing constructs which only differ in syntax and visibility.

@pnkfelix
Copy link
Member Author

@Kimundi Hmm I have not considered three variants for extern crate. I will add in your extern crate <ident> as <ident>; option in the Alternatives section.

Note that I only put it in the Alternatives.  I think there is a
pretty good argument that whether to do this or not is orthogonal to
this RFC, and the only reason to fold it into this RFC is to avoid the
process overhead of filing a seprate RFC.
@nikomatsakis nikomatsakis merged commit f396647 into rust-lang:master Aug 12, 2014
@pnkfelix
Copy link
Member Author

(merged as RFC 47)

@Centril Centril added A-syntax Syntax related proposals & ideas A-modules Proposals relating to modules. labels Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-modules Proposals relating to modules. A-syntax Syntax related proposals & ideas
Projects
None yet
Development

Successfully merging this pull request may close these issues.