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

Turn capitalization conventions into language rules for 1.0 #154

Conversation

glaebhoerl
Copy link
Contributor

@glaebhoerl glaebhoerl changed the title Turn capitalization conventions into language rules Turn capitalization conventions into language rules for 1.0 Jul 4, 2014
local binding otherwise. This context-dependent meaning presents a significant
vulnerability to mistakes and accidental breakage. The convention of writing
`enum` variants and `static`s uppercase and local bindings lowercase, if it is
adhered to, eliminates this vulnerability, but it is only a convention.
Copy link
Member

Choose a reason for hiding this comment

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

But there are other conventions which could also prevent such mistakes, right? So a lint seems appropriate since we are guiding the user to a particular convention, but as long as they follow some convention, they will be OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea is that guarantees are valuable. A convention is not a guarantee, especially not unless you can ensure that Rust code using one convention will never have to come into contact with Rust code using a different convention.

@SiegeLord
Copy link

The motivation is just not at all convincing. The match issue has far better (i.e. non-stylistic) proposed solutions (e.g. rust-lang/rust#4639 for the variant/variable ambiguity, I'm sure there have been suggestions how to resolve the static variable ambiguity (e.g. disallow them in matches)). If this is really a big enough wart to warrant such drastic solutions, then the wart should be fixed with a more limited solution.

Additionally, this doesn't work well with FFI and automatic binding generators.

@emberian
Copy link
Member

emberian commented Jul 4, 2014

Yeah, I find the FFI argument the most convincing. You really don't want
to use different names than the thing you are binding.

On Fri, Jul 4, 2014 at 4:43 PM, SiegeLord notifications@github.com wrote:

The motivation is just not at all convincing. The match issue has far
better (i.e. non-stylistic) proposed solutions (e.g. rust-lang/rust#4639
rust-lang/rust#4639 for the variant/variable
ambiguity, I'm sure there have been suggestions how to resolve the static
variable ambiguity (e.g. disallow them in matches)). If this is really a
big enough wart to warrant such drastic solutions, then the wart should be
fixed with a more limited solution.

Additionally, this doesn't work well with FFI and automatic binding
generators.


Reply to this email directly or view it on GitHub
#154 (comment).

http://octayn.net/

@Manishearth
Copy link
Member

Please, no. this is bad enough.

extern functions and other things will break this. I really don't like the idea of gleaning information from variable names.

@lilyball
Copy link
Contributor

lilyball commented Jul 5, 2014

👎 I don't like the idea of semantic case. Go has it bad enough in using case as a public/private distinction, but using it to define different classes of identifiers that are valid for use in different contexts seems far worse.

Also, how is this supposed to handle XID_Start characters that are neither lowercase nor uppercase? For example, "ਫ਼" (U+0A2B GURMUKHI LETTER PHA) is apparently neither lowercase nor uppercase (according to the .is_lowercase()/.is_uppercase() methods in Rust). I realize that non-ascii identifiers are currently feature-gated, but they are still usable once enabled.

@alexchandel
Copy link

👎 for named-parameter function calls with braces. Ridiculously inconsistent.

  • Since we're not going with that, variable_name { a: foo, b: bar } can still be a functional update, and doesn't require semantic casing.

👎 for syntactic differences between fn calls and tuple structs. It's enough that the identifiers are unique.

👎 for grandfathering. This isn't Java, there's no need to riddle ourselves with inconsistencies so early in the game. We can easily change to U32, F32, or something else.

👎 for turning builtin types into keywords. This isn't C++ with its ridiculous wchar_t keyword.

suppose we want to allow accessing the fields of tuples and tuple structs as .0, .1, .2, etc. Pretty soon someone will ask: can I use a static uint declaration instead of a literal?

No, for the same reason you can't use a static &str to access a struct's field. And because identifiers are unique, so semantic casing isn't necessary for either feature.

There was a recent proposal to remove the ' sigil for lifetimes. If types are always uppercase and lifetimes are always lowercase, they are syntactically unambiguous even without the sigil.

In that proposal, it's shown that lifetimes are unambiguous anyway, if they are moved before the &.

@glaebhoerl
Copy link
Contributor Author

It seems to me that people are reacting to this idea on a visceral, emotional level, which I don't really understand. My guess is that it's because of the alienness of the idea in the context of most mainstream languages. But if people want to exclaim, "it's bad enough in $LANGUAGE", the example they should be using isn't Go, but Haskell. They do exactly the same thing (as what I'm proposing, not as Go), and it works pretty well for them. Haskell is a smart language in many ways.

I'll try to address the individual arguments.


@SiegeLord

The match issue has far better (i.e. non-stylistic) proposed solutions (e.g. rust-lang/rust#4639 for the variant/variable ambiguity

I'm not even sure how that could work. If the identifier has the name of an enum variant, then it's not a variable, therefore the lint doesn't apply. If it's a variable, then it doesn't have the name of an enum variant, therefore the lint doesn't apply. Even if I'm missing something, it seems like this would only catch a subset of the cases.

I'm sure there have been suggestions how to resolve the static variable ambiguity (e.g. disallow them in matches)

I tried suggesting this previously a couple of times, and naturally, people objected. I've come around to agreeing with them.

The reason is that static declarations are two things at the same time: on the one hand, they're runtime objects whose lifetime is the life of the whole program, while on the other hand, they're declarations whose definition is available to the compiler at compile time. Under the first interpretation, which I had been assuming previously, allowing them in matches is very weird, but under the second interpretation, it couldn't be more natural.

If this is really a big enough wart to warrant such drastic solutions, then the wart should be fixed with a more limited solution.

I think it's a pretty big wart. (And I don't think this is a drastic solution, especially as fixing the wart is only one of the reasons I think we should do it.) And, again, Haskell runs into the exact same issue and solves it the exact same way. But if you can come up with a more limited solution that people are willing to accept, you will have my everlasting gratitude.


@cmr

Yeah, I find the FFI argument the most convincing.

Me too! But not convincing enough. Broken record at this point, but Haskell does the same thing, and they're doing fine. Furthermore, automatic binding generators seem especially well suited to automatically, mechanically, and predictably adjusting identifiers where necessary.


@kballard

Also, how is this supposed to handle XID_Start characters that are neither lowercase nor uppercase? For example, "ਫ਼" (U+0A2B GURMUKHI LETTER PHA) is apparently neither lowercase nor uppercase (according to the .is_lowercase()/.is_uppercase() methods in Rust). I realize that non-ascii identifiers are currently feature-gated, but they are still usable once enabled.

Did you read the proposal?


@alexchandel
Perhaps you missed the parts immediately before and after the bulleted list where I tried to make it clear that the value of the particular ideas in it is not the point. For all I know, it could end up being your pet feature whose viability for inclusion in a backwards-compatible way after 1.0 depends on being able to distinguish different types of identifiers.

👎 for grandfathering. This isn't Java, there's no need to riddle ourselves with inconsistencies so early in the game. We can easily change to U32, F32, or something else.

In theory, I agree with you. In practice, if you want to submit another RFC proposing to break every Rust program in existence for purely superficial reasons, be my guest. It will gain 100 comments in a day, and go nowhere. I'm surely not going to do it.

In that proposal, it's shown that lifetimes are unambiguous anyway, if they are moved before the &.

Once again, the existence of an alternative solution which people are also unwilling to accept is not a persuasive counterargument. (And the lifetimes thing was, like the others, just an example, not a proposal.)

@alexchandel
Copy link

@glaebhoerl

Perhaps you missed the parts immediately before and after the bulleted list where I tried to make it clear that the value of the particular ideas in it is not the point

Any desirable features that result from a proposed change provide support for that change. "Being able to distinguish classes of identifiers based on their capitalization opens up significant room for adding new features to the language" isn't a convincing argument for mandatory capitalization if the new features aren't particularly desirable, or if mandatory capitalization isn't necessary for them.

@glaebhoerl
Copy link
Contributor Author

The logic wasn't that we should make the change because then, we can do the things in the list. It was that, if I could think of five ideas while I was writing the proposal, there are probably lots of other situations where the same capabilities might come in useful.

@matthieu-m
Copy link

You might want to add a section on dealing with FFI. In C you may have a struct with a lower-case name or a function with an upper-case name, I would suggest in this case that there be two names:

  • one name in Rust, following the naming conventions
  • one name for exporting to C, matching the expected C name #[extern("C", "some_type")]

@glaebhoerl
Copy link
Contributor Author

@matthieu-m Perhaps. :)

In C you may have a struct with a lower-case name or a function with an upper-case name

I don't think struct names are relevant, because they're not used for linking?

one name for exporting to C, matching the expected C name #[extern("C", "some_type")]

I think we already have this as link_name, from the manual:

link_name - the name of the symbol that this function or static should be imported as.

identifiers. Thus, they are legal as identifiers for anything in the
uppercase-class, not just types, and not for anything in the lowercase-class.

3. Turn them into keywords.

Choose a reason for hiding this comment

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

Or rename them to Int, UInt, I8, U8, etc.

@SiegeLord
Copy link

They do exactly the same thing (as what I'm proposing, not as Go), and it works pretty well for them. Haskell is a smart language in many ways.

I personally think that syntax is Haskell's weakest point.

If the identifier has the name of an enum variant, then it's not a variable, therefore the lint doesn't apply.

This lint would apply to cases like this:

use foo::A; // whoops, forgot to import all the variants

mod foo
{
    pub enum Bar
    {
        A,
        B,
        C
    }
}

fn main()
{
    match A
    {
        A => (),
        B => (), // A variable that would trigger the lint
    }
}

Which is the by far most common way you hit this ambiguity.

it couldn't be more natural.

I don't disagree that it's natural, but not all natural things need to be supported if they have a high potential for error. It doesn't seem terrible to me to force doing this with static variables:

match 1
{
    x if x == STATIC_VAR => ()
}

Pretty much 100% of my usage of this feature comes from transducing C enums into Rust enums, so I wouldn't be burdened by this (the FFI-Rust bridge always looks a bit ugly). I certainly prefer this to enforced capitalization.

It was that, if I could think of five ideas while I was writing the proposal, there are probably lots of other situations where the same capabilities might come in useful.

I strongly dislike all those ideas, so in my opinion, the fact that all these ideas are enabled by this RFC is an argument against it. Giving more freedom to language designers is the worst thing you can do, from my POV. Giving this freedom because you've introduced some non-discoverable rules into the language is even worse.

@bvssvni
Copy link

bvssvni commented Jul 5, 2014

Some thoughts:

  • Should type aliases be excepted? int can be renamed to Int and then given a type alias int.
  • Functional struct update can use mut variable_name { a: foo, b: bar } to solve the ambiguity (if I understood this correctly).
  • Most of the practical benefit is enforced through lints. I don't want language features to depend on capitalization, because then it can't be removed.
  • Go uses it to separate public/private only. I am not sure that the same benefit will translate to Rust as well because it does not apply in the same way. Using it for a set of language blocks is not user friendly.
  • Translating code from another languages might become harder. In some cases you want to follow the conventions from existing API.
  • In some algorithms reflecting mathematical notation, having upper case local variables might increase readability. For example, http://en.wikipedia.org/wiki/Einstein_notation

To consider under the 'Alternatives':

@bstrie
Copy link
Contributor

bstrie commented Jul 5, 2014

Separate identifiers into two classes: ones which must start with an uppercase character, and ones which must start with a lowercase character.

This is precisely the wrong way to do it. Instead, you would want to have one class of identifiers that are forbidden from starting with a lowercase character, and one class of identifiers that are forbidden from starting with an uppercase character. This allows you to entirely sidestep the issue of Unicode compatibility, and, assuming that Unicode identifiers remain behind a feature flag, also allows you to retain the "adding new features backwards-compatibly" benefits mentioned elsewhere.

That said, I am against this proposal. The FFI argument is too strong to ignore. Pointing out that it works for Haskell is not convincing; Rust cares much more about cleanly interfacing with C than Haskell does.

I'm also not convinced that the other benefits mentioned are worth much. The proposed syntax for named function arguments is quite a stretch. I'm not convinced that indexing into tuples is useful, and even if we wanted it I don't see why we wouldn't just use the existing indexing syntax (or why we would re-use the . operator instead of coming up with a new one). Sigil-less lifetimes can be done by putting the lifetime name before the &. And saying that there exist problems with match is alarmism.

I do think it's important to have an idiomatic Rust style, which is why I'm grateful for the current lints, and I'm happy that they're warn-by-default instead of allow or deny. A hardline stance doesn't pull its weight here.

@bstrie
Copy link
Contributor

bstrie commented Jul 5, 2014

Despite my negativity, I do want to thank you for taking the time to make a well-written RFC. If only all our bikeshedding were so thoughtful.

@netvl
Copy link

netvl commented Jul 5, 2014

-1. Personally, I don't find pro arguments convincing (examples like optional arguments really do look weird), and FFI argument against it is very strong.

I also think that case enforcement is just wrong and is just unnecessary limit for the programmer. Lint is more than enough for it.

@alexchandel
Copy link

@glaebhoerl Although I don't think it should be mandatory, adherence to the standard style should probably be encouraged as much as possible, to avoid the potential bugs the RFC describes. Why not add a styler/formatting tool to rust?

Go has go fmt source.go. What about something like rust fmt source.rs or rustf source.rs? It would re-format the source code to Rust conventions, and rename fields idiomatically whenever possible.

@matthieu-m
Copy link

@bstrie: I keep seeing mentions of the FFI issue, and I am afraid I do not see the problem.

It seems it is possible to have a name for Rust, and a link name for linking, and therefore it does not matter if one cannot use the exact same identifier in Rust than in the target language.

However, I see an issue if the style is NOT uniform: tooling. For example editors can be configured to help you follow a certain style, in general, by pointing out irregularities or even automatically clean up behind you. If the style is almost uniform (except for some FFI items), then those editors will have to (somehow) understand the FFI rules which requires being able to look-up the relevant identifiers in their module to see whether they are FFI items or not, etc... this goes way beyond a simple styler/formatter! And requires either re-implementing libsyntax or managing to link with it from whatever language the styler/formatter is written in... if it is at all possible (not purely declarative).

@glaebhoerl
Copy link
Contributor Author

I also think that case enforcement is just wrong and is just unnecessary limit for the programmer.

I suspect this is the underlying sentiment in most instances, and we're all just trying to come up with more sophisticated rationalizations. This is not a ding; I do it too; it comes with being human. That said, I wish that, along with saying "I don't like it", people would try harder to locate the true source of their dislike. Maybe we can learn from it. Maybe I'll even find it convincing. Your dislike is noted, but it's not an argument.

To me, doing this sounds much more like a free lunch than like a freedom-trampling restriction. We're already following these rules in the vast majority of cases. All we need to do is to formalize them, and then we get various benefits for free. (And one more time with feeling, the benefit is not being able to do any of the five particular things I chose to throw out as examples, but in general the ability to distinguish certain kinds of identifiers from one another syntactically.)

I acknowledge the FFI issue, but I don't think it rises beyond the level of an annoyance. You need two rules:

  1. If it starts with an uppercase character in the original API, but in Rust it would only be legal with a lowercase character, then in Rust it begins with the lowercase version of that character.
  2. If it starts with a lowercase character in the original API, but in Rust it would only be legal with an uppercase character, then in Rust it begins with the uppercase version of that character.

Automatic bindings generators can apply these rules automatically, and consumers of the bindings can apply the rules in their heads when recalling the names of things. It's not rocket surgery.


@SiegeLord

I personally think that syntax is Haskell's weakest point.

Could you explain why?

This lint would apply to cases like this:

I see. Thanks.

(I wonder if we could have variants come into scope along with the enum itself? Conceptually they're just the dual of struct fields. But this is a separate issue.)

It doesn't seem terrible to me to force doing this with static variables:

match 1
{
    x if x == STATIC_VAR => ()
}

I tried floating this as recently as three weeks ago. According to pcwalton, "I used to argue that guards were sufficient, but the community pushback was overwhelming and consistent. People really really expect to be able to match on constants."

And on top of that, (a) I now agree that it should be possible, and (b) removing it doesn't even solve the problem, because the same issue exists for enum variants.

I certainly prefer this to enforced capitalization.

I do think we should keep brainstorming alternative solutions, even if I don't think the odds are good. For instance, allegedly Old Rust used to require writing Foo. when using the enum variant Foo in a pattern, to disambiguate it from a binding. We could flip that around and require disambiguating the bindings:

// a pun on `let` statements
match FromStr::from_str(my_str) {
    Some(let val) => frobble(val),
    _ => ...
}
// a pun on the existing explicit `@name` binding syntax
match FromStr::from_str(my_str) {
    Some(@val) => frobble(val),
    _ => ...
}
// a pun in English
match FromStr::from_str(my_str) {
    Some(as val) => frobble(val),
    _ => ...
}

but somehow, I suspect that any proposal to require more syntax in matches would be met with nothing but a chorus of 👎s. Which, granted, is not necessarily a worse reception than this one has gotten, but still doesn't get us anywhere. And it's not even clear that let statements could be exempted from this, in which case it's game over. Better ideas badly needed.

I strongly dislike all those ideas, so in my opinion, the fact that all these ideas are enabled by this RFC is an argument against it.

Fair enough, but then we're back to dislike.


@bstrie

Instead, you would want to have one class of identifiers that are forbidden from starting with a lowercase character, and one class of identifiers that are forbidden from starting with an uppercase character. This allows you to entirely sidestep the issue of Unicode compatibility

Interesting idea, but wouldn't this defeat the purpose? The purpose is to be able to guarantee that certain kinds of things can never have the same name. If neither-uppercase-nor-lowercase characters are allowed in all cases, there's no longer a guarantee.

And saying that there exist problems with match is alarmism.

This is like when people try to impress C++ programmers by showing that in Rust,

let x = some_thing();
return &x;

will fail to compile. And the C++ folk shrug and say, "So? Every C++ compiler gives a warning for that. It's a solved problem." And the Rustic folk put their hands to their heads, because they know it's bigger than that, but they don't see how to communicate it to the people from C++.

I really, really don't like saying to people, "We've left some landmines in the language... but don't worry! You can reduce your risk of stepping on them if you use this lint and that convention.", when we have it within our power to not plant any landmines. The point is that guarantees are valuable. It means not having to do due diligence, or ever think about "well, what if...". To the question, "What are the chances of that ever happening?", I want to be able to answer, "0%".

@pczarn
Copy link

pczarn commented Jul 7, 2014

The naming conventions have exceptions. I don't like the rigor of language rules concerning capitalization.

Better disallow shadowing a valid name with one that doesn't follow conventions:

enum Bar {
    Foo(int) // follows the convention
}

fn main() {
    fn Foo(_: int) {} // should cause an error in this specific example
    println!("{}", Foo(1));
}

@glaebhoerl
Copy link
Contributor Author

@matthieu-m I put in a bit about FFI.

@pczarn

The naming conventions have exceptions. I don't like the rigor of language rules concerning capitalization.

Why?

Better disallow shadowing a valid name with one that doesn't follow conventions:

What would this accomplish?

@pcwalton
Copy link
Contributor

pcwalton commented Jul 9, 2014

It doesn't seem terrible to me to force doing this with static variables:

Note that I used this argument to resist adding this feature, but it was constantly asked for.

@lilyball
Copy link
Contributor

lilyball commented Jul 9, 2014

@pcwalton I too find it a little odd that statics are allowed to be used in match arms but not variables, although it isn't all that different from nullary enum variants (as those are just values as well).

I think Swift may have actually gotten this one right, forcing all enum variants to be scoped under the enum and allowing the scope to be inferred from type so you can just say .EnumVariant, because that completely sidesteps the entire issue of distinguishing between enum values and let-bindings in match arms. Their funky use of let in the patterns also allows for matching arbitrary values in the match arm.

But of course it's a bit too late to be making a sweeping change like that to Rust.

In the meantime, if statics in patterns are an issue, maybe we should change it so references to statics must be prefixed with the keyword static:

match foo {
    Some(static STATIC_VAR) => stuff(),
    _ => bar()
}

Not that I'm seriously suggesting we make this change; as I said before, statics are pretty much the same case as nullary enum variants, and we can't solve the latter without much more sweeping changes.

@SiegeLord
Copy link

I suspect this is the underlying sentiment in most instances

I see nothing wrong with people rejecting this because of mere 'dislike'. Subjective reasons are omnipresent in language design.

According to pcwalton, "I used to argue that guards were sufficient, but the community pushback was overwhelming and consistent. People really really expect to be able to match on constants."

Note that I used this argument to resist adding this feature, but it was constantly asked for.

This just means that the issue (the ambiguity between variables and variants/static variables) is not a big enough problem to those people to make the pain of these solutions worth it. Personally, I am perfectly content in leaving this wart in because I think it's not a big wart as evidenced by this type of sentiments.

@glaebhoerl
Copy link
Contributor Author

@SiegeLord

I see nothing wrong with people rejecting this because of mere 'dislike'. Subjective reasons are omnipresent in language design.

I'm a hopeless idealist, but I would hope for RFCs to be discussed using meaningful arguments grounded in reason, with at least the theoretical possibility of a participant being persuaded by another's arguments, and decided on the merits. Even in discussions on truly superficial aspects of the language such as whether to keep the ' sigil on lifetimes and whether to use <> or [] for generics, in most cases people managed to marshall coherent, logical, even evidence-based arguments for their position. A string of +1s and -1s is not what I think these discussions should be about.

And subjective is fine, but "I don't like it" is not even a reason. It's a conclusion.

This just means that the issue (the ambiguity between variables and variants/static variables) is not a big enough problem to those people to make the pain of these solutions worth it. Personally, I am perfectly content in leaving this wart in because I think it's not a big wart as evidenced by this type of sentiments.

I think this sort of complacency and optimism is ill-advised. "Well, it's not really a problem in practice" and "it hasn't bitten us so far, so it should be fine" are the kind of sentiments which later tend to go down as famous last words. A few years from now, I think this is likely to be regarded as one of the few unfortunate mistakes of an otherwise exceptionally well-designed language.

@Thiez
Copy link

Thiez commented Jul 13, 2014

I think the "it hasn't bitten us so far" argument is quite reasonable, given that an entire compiler is written in Rust, and "so far" spans a period of several years.

@glaebhoerl
Copy link
Contributor Author

The entire compiler is written by people who have the most intimate familiarity with the language that anyone's ever going to have, and who have adopted a set of informal rules for capitalization to avoid getting bitten by it, which are the same rules that this proposal seeks to formalize.

"If it hasn't bitten you yet, it's going to bite you later" is something like an iron law in programming, especially when "later" involves doing things at larger scales than previously. And that's again something like the whole justification for Rust's rigorous type system, which seeks to make entire classes of errors impossible, instead of merely trying to make them less likely. I don't see why the same mentality shouldn't be applied to the rest of the language.

@dobkeratops
Copy link

IMO this is much better as warnings rather than errors. There's translations of legacy interfaces, e.g. I much prefer gl code to look like gl code anywhere else; and supposedly theres foreign languages where it doesn't apply. I suspect rust lets you syntax highlight by context a lot more already ... :Type ... Trait for Type.. as Type ... etc. So the capitalisation rule is just something subjective
I was wanting to roll macros to help reduce boilerplate for overloading (indirection traits) which would ideally mean generating trait-names from function-names..

@zwarich
Copy link

zwarich commented Jul 13, 2014

@glaebhoerl There is actually a lot of code in the compiler that currently violates these rules.

@glaebhoerl
Copy link
Contributor Author

@nick29581

#154 - Turn capitalization conventions into language rules - > glaebhoerl
Make our capitalisation warnings into errors.
Mostly negative feedback but some positive too. Many problems identified including all the violations in existing code, languages with different capitalisation rules, FFI.
Perhaps this should get discussion at a meeting, but I would recommend close.

This is too kind. As far as I can tell the feedback has been not just mostly but almost uniformly negative, with a couple of people seemingly neutral.

To recap where this stands from my perspective:

People have identified two issues which I think are real, but not very big. Most commonly cited was FFI. As noted in the RFC, this seems easy to resolve by just having bindings generators apply a mechanical transformation such that foreign identifiers which don't follow Rust's capitalization rules simply get their capitalization adjusted so that they do. This doesn't sound like the end of the world, and I don't think it would be more than an annoyance. The other was unicode identifiers (which are not currently legal) and alphabets without a case distinction. Again, I think we could come up with ways to resolve this when we reach that point (for instance, by saying that such characters always count as uppercase and must be prefixed with _ for use as lowercase identifiers).

On the other hand, doing this would fully resolve a very real and in my opinion troubling semantic wart with respect to name resolution in patterns, which seems very difficult to resolve any other way, would open up greater space for backwards-compatible language changes in the future, and would not have much of a real cost, as the large majority of existing code already follows these rules.

As far as I can tell, most people seem to be standing on principle for their right to name their identifiers however they like, even if they rarely end up exercising it.

The other logical underpinning of the proposal, alongside that it has benefits and not much of a cost, is that it could be rescinded backwards-compatibly after 1.0, should we choose to, but not added. As such, it may be prudent to add the rules before 1.0 just to keep our options open, if there's even the possibility that we might want to have them. A potential compromise here would be to just put the use of non-conformant identifiers behind a feature gate, instead of banning them outright, which would be easier to reverse should we decide that the rules aren't carrying their weight (in effect, change them from opt-in with the current lints to opt-out).

But if opposition to the idea is universal and there's basically no chance of it being considered desirable, then it's probably better not to bother.

@liigo
Copy link
Contributor

liigo commented Jul 21, 2014

A big -1! A bad idea to distinguish public items or not! Unacceptable.

@glaebhoerl
Copy link
Contributor Author

@liigo This has nothing to do with public items, I'm not sure what you're thinking of.

Also, could you please be a bit more detailed and constructive? This isn't a shouting match. Thanks.

@steveklabnik
Copy link
Member

I am actually really pro making this lint into a language rule, personally. I just haven't said anything because I knew this thread would end up really noisy.

@alexcrichton
Copy link
Member

Thanks for taking the time to write up this RFC! This was discussed at today's triage meeting and the decision was to close this for now. Rust has trended largely towards C in many of its design decisions, including having no restrictions on the format of identifiers. At this time we would like to continue that trend and not turn these into language rules but rather retain the middle ground of having a default-warn lint for rules such as these.

@glaebhoerl
Copy link
Contributor Author

Rust has trended largely towards C in many of its design decisions, including having no restrictions on the format of identifiers. At this time we would like to continue that trend

FWIW, this is a reasonable argument and I've been waiting for someone to make it.

@liigo
Copy link
Contributor

liigo commented Jul 25, 2014

Nice to see it was closed. I don't like capitalization conventions.

@pnkfelix
Copy link
Member

@liigo You established your stance up above.

If everyone who had opposed to a particular RFC chimed in after closure with a "thank goodness!", it would be a lot of noise. Such behavior would also be rude (and thus in violation of the Rust community code of conduct). Such curt dismissal is quite disrespectful of the effort put in by the RFC author.

I assume that you do not mean to be rude, but I also ask that you consider more carefully whether the terse comments you post are actually adding value to the discussion; otherwise all they add are negative vibes.

If you have questions, or do not understand the feedback I am providing, I recommend you chat about it directly with me or another core team member, via email or on IRC; my IRC nick is pnkfelix.

@liigo
Copy link
Contributor

liigo commented Jul 25, 2014

Sorry!
2014年7月25日 下午7:58于 "Felix S Klock II" notifications@github.com写道:

@liigo https://github.com/liigo You established your stance up above
#154 (comment).

If everyone who had opposed to a particular RFC chimed in after closure
with a "thank goodness!", it would be a lot of noise. Such behavior would
also be rude (and thus in violation of the Rust community code of conduct
https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct).
Such curt dismissal is quite disrespectful of the effort put in by the RFC
author.

I assume that you do not mean to be rude, but I also ask that you consider
more carefully whether the terse comments you post are actually adding
value to the discussion; otherwise all they add are negative vibes.

If you have questions, or do not understand the feedback I am providing, I
recommend you chat about it directly with me or another core team member,
via email or on IRC; my IRC nick is pnkfelix.


Reply to this email directly or view it on GitHub
#154 (comment).

withoutboats pushed a commit to withoutboats/rfcs that referenced this pull request Jan 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.