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

Make the turbofish syntax redundant #2544

Open
wants to merge 16 commits into
base: master
from

Conversation

Projects
None yet
@varkor
Copy link
Member

varkor commented Sep 17, 2018

Make disambiguating generic arguments in expressions with :: optional, allowing generic arguments to be specified without ::. This makes the "turbofish" notation no longer necessary.

Rendered

This makes the following valid syntax:

struct Nooper<T>(T);

impl<T> Nooper<T> {
    fn noop<U>(&self, _: U) {}
}

fn id<T>(t: T) -> T {
    t
}

fn main() {
    id<u32>(0u32); // ok
    let n = Nooper<&str>(":)"); // ok
    n.noop<()>(()); // ok
}

The syntax ambiguities (a<b,c>(d)) and a<b>>c are resolved in favour of generic expressions.


This is an updated and more considered version of the RFC put forward a little while ago.
Thanks to @Centril, @comex, @joshtriplett, @kennytm, @petrochenkov, @rpjohnst, @scottmcm, @ubsan and @xfix for their feedback (and everyone else who chipped in)!

cc @aturon, @eddyb, @withoutboats

@Centril Centril added the T-lang label Sep 17, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Sep 17, 2018

However unusual a corner case, I feel very uncomfortable with making breaking parser changes for existing code.

On the other hand this change is a perfect candidate for edition switches since it can be entirely crate-local. I’d much prefer it only applied in Rust 2018 or, if it’s too late, in the following edition. The turbofish has been with us since 2011, before Rust 0.1. We can live with it a few more years.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Sep 17, 2018

However unusual a corner case, I feel very uncomfortable with making breaking parser changes for existing code.

There's precedent for doing this with rust-lang/rust#53854.

I’d much prefer it only applied in Rust 2018 [...]

Nominating for the next meeting to discuss this possibility.

@Centril Centril added the I-nominated label Sep 17, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Sep 17, 2018

I have not tried reading that diff, but the title of that PR says “edition changes”. So… is that an agreement with my comment?

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Sep 17, 2018

@SimonSapin no; the precedent was for applying the grammar changes in Rust 2015.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Sep 17, 2018

I was not involved in that discussion but my opinion is the same. I think this is a bad precedent.


An initial implementation is present in https://github.com/rust-lang/rust/pull/53578, upon which the
implementation may be based. The parser will now attempt to parse generic argument lists without
`::`, falling back on attempting to parse a comparison if that fails.

This comment has been minimized.

@petrochenkov

petrochenkov Sep 17, 2018

Contributor

This is not a language argument, but you are underestimating the work required to do this correctly.
On encountering < parser needs to enter some kind of new speculative mode suppressing all side effects, including non-fatal diagnostics.
We can ignore these details if the rollback is done only as a part of best-effort error recovery, but not if it's a part of the language, so the feature has some global effect on parser implementation rather than just calling self.clone() in one place.

This comment has been minimized.

@petrochenkov

petrochenkov Sep 17, 2018

Contributor

Additionally, parser can accept pretty strange things and then report "semantic" errors later, but we won't be aware of these errors when disambiguating with backtracking.
This problem already exists in the formulation "what exactly is accepted under cfg(false)?", but in that case it's probably easier to fix e.g. by doing AST validation during expansion.

This comment has been minimized.

@varkor

varkor Sep 17, 2018

Member

I noticed this was necessary with rust-lang/rust@307ea60, though I imagined this wasn't sufficient for a final implementation. The language in the RFC wasn't intended to insinuate how difficult the task would be: the proof of concept is definitely only that!

@dherman

This comment has been minimized.

Copy link

dherman commented Sep 17, 2018

However unusual a corner case, I feel very uncomfortable with making breaking parser changes for existing code.

I thought it might be helpful to weigh in with my experience at TC39, which spends a lot of effort on retaining compatibility but nevertheless does sometimes make technically breaking changes. It's true that the bar is high for breaking changes, which is why it's good to get empirical evidence about real-world breakage. But at the end of the day, we've found with JavaScript that -- if we are cautious and use good judgment -- there is some budget for de jure incompatible changes that are de facto compatible. To me, the fact that even something as high-usage and conservative about backwards compatibility as JavaScript is able to make changes like this suggests that Rust can as well.

My feeling is that if the language and ecosystem are better off for it, and it doesn't cause churn in practice, Rust should be willing to make formally breaking changes like this. (And given my personal experience both with teaching Rust to newcomers at work and designing APIs to try to avoid turbofish, I personally hope we do!)

@estebank

This comment has been minimized.

Copy link
Contributor

estebank commented Sep 17, 2018

And given my personal experience both with teaching Rust to newcomers at work and designing APIs to try to avoid turbofish, I personally hope we do!

I would be interested in hearing (possibly off thread to avoid spamming) about what you've found the largest problems for newcomers when it comes to turbofish. I can think of a few:

  • discoverability
  • "weird" syntax
  • understanding of the semantics

Also, I am interested in hearing what the main reason(s) for avoiding the need of turbofish in your API surfaces are that would be rendered moot by changing the syntax.

I am personally of the inclination that rustc should actually accept a superset of valid Rust code for more specific diagnostic errors, which would make merging @varkor's change almost as-is to inform the suggestions emitted something I would enthusiastically push for as it would help with the three items listed above, while changing the parsing semantics away from a regular syntax by accepting now-incorrect code a bit worry-some as it would put a higher burden on third-party implementers. (I understand the low likelihood of anyone actually trying to make an independent Rust compiler that matches nightly or even current stable rustc, but still.)

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Sep 17, 2018

@dherman Fair points, but I think that the equation is significantly affected by Rust having this edition mechanism that JavaScript doesn’t.

We’re doing opt-in switches already, let’s use them for what they’re for.

@rpjohnst

This comment has been minimized.

Copy link

rpjohnst commented Sep 17, 2018

On the question of teaching, we also ought to consider the affect of type ascription. If we had type ascription but not this, we could teach and use the language entirely without turbofish, without worrying about compatibility or edition switches or weird syntax or backtracking.

@pcwalton

This comment has been minimized.

Copy link
Contributor

pcwalton commented Jan 12, 2019

To reiterate, if we cap the lookahead at any finite level of nesting of brackets (say, 16), then we will have an LL(∗) grammar, and therefore an unambiguous one. So, if our premise is that maintaining the LL(∗) property is important, the relevant question is whether having the turbofish is more inconsistent or having a finite nesting level is more inconsistent.

@H2CO3

This comment has been minimized.

Copy link

H2CO3 commented Jan 12, 2019

@Manishearth You have a good point there that I was just going to write more about. But first, a reaction to an earlier comment:

Every time I encounter the need arise for an arbitrary numerical limit, I see a big red flag, spelling out "hack". And I wonder, and it just somehow appears misguided to me to resort to a hack in order to kinda-sorta, technically (but quite "dishonestly") get LL(k) with a sizeable portion of the real-life disadvantages of LL(*) / non-LL(k) / unbounded lookahead, whereas we could just go with real, actual LL(k=small) in the first place.

And now to the point of subjectivity. Yes, several aspects of this discussion are subjective. But I also noticed that along these lines, the (perceived) advantages of not having to type out the turbofish are being considered with a weight disproportionately high compared to the (perceived) disadvantages of the resulting ambiguity, first and foremost in human readers of the code. (Incidentally, I think in this issue human-readability is more important than machine-readability, because it's exposed to users directly, raw and naked, so it's not only an implementation detail anymore.)

Relatedly, I see it as a fallacious line of reasoning to first assert that beginners are not good enough at understanding and/or memorizing the literally 1-bit decision rule of "the fish is needed in value context but not in type context", then dismissing how they might equally struggle with the resulting ambiguities should the turbofish be gone. Conversely, if we believe and presume that some/most people are not going to be annoyed or misled by such ambiguities, why don't we also believe that having to memorize when to type and when not to type two colons is not an issue for some/most programmers?

There is an entire series of arguments in favor of this change based on ergonomics, yet these arguments seem to deny that in addition to people who find the turbofish more annoying than the ambiguity, there are also people who find ambiguities more annoying than having to memorize the turbofish.

@rpjohnst

This comment has been minimized.

Copy link

rpjohnst commented Jan 12, 2019

I hope this isn't just more retreading, but thanks to @ltratt's excellent #2544 (comment) and @nagisa's #2544 (comment), I'd like to elaborate a bit on #2544 (comment):

I would much rather have extra parser power leveraged toward improvements in error messages, editors, etc. and not need it otherwise than the reverse.

Today Rust's grammar does not require any backtracking (IIUC). However, rustc already does plenty of it regardless- this is purely to improve error recovery and messages. If backtracking becomes an actual tool required for correctness, that makes rustc's job there harder, because there's less "negative space" in the grammar for it to bounce off.

Here's another example of this that I don't think has been mentioned: I work on a C++ IDE, and doing a full parse of the user's file often takes way too long. (I believe much of this is due to implementation, rather than language, but often that's just reality- e.g. this also applies to the RLS.) So for some operations, we have to find ways to skip things or jump in in the middle- and having the ability to use a more powerful parser than required by a successful straight-line compile is very useful here. (And no, this is not about the lexer hack- it does not increase the class of grammar we use in a straight-line compile, and it's not what we're working around here....)

In general, this grammatical negative space is valuable in and of itself, both for compilers and IDEs. When a user writes something wrong, if it falls into negative space it's more likely that we can tell what they intended based on what valid grammar is nearby. But if we extend the grammar, there's less negative space and it's more likely that the user will have meant something else, or that their wrong code already does mean something else.

So regardless of whether this particular change immediately affects this side of things, it still interacts with any future changes we may make. What I would prefer to take from @varkor's experiments here is not that we can make this change with "only a little compatibility break" (ugh) but that it's an extremely effective method of error recovery! Let's use it for that purpose, and focus on making the edit/compile/fix loop tighter, through a faster cargo check, or rustfix and IDE integration.

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Jan 12, 2019

@rfcbot concern needs-better-crater-run

It would be good to prepare a lint catching parsing ambiguity cases with more future-compatibility in mind than it was done in rust-lang/rust#53578, like f<1, 2>() and f<1 + 2>().
I planned to do it, but delayed the work due to edition-related tasks, perhaps now it's a good time to return to it.

@graydon

This comment has been minimized.

Copy link

graydon commented Jan 12, 2019

most of the arguments here boil down to more or less irredeemable differences of personal axioms

I agree, and I don't want to be making pointless arguments in bad faith or anything. This may not be the ideal place to litigate the disagreement, but it's clear evidence to me that the chorus of "please stop changing things" input from the community is being flatly ignored by the language team. I said as much in as plain language above as I could: the language team seems to be unable, and I think given the conversation I've seen here and elsewhere simply unwilling, to minimize or halt changes to the language. Lip service is paid, but the changes keep being justified and pushed through. This change will of course not break the language, but crossing a long-held design constraint for a seemingly minor papercut is illustrative of the pattern.

I thought I was perceiving this pattern from a distance over the past couple years and it motivated me to participate in the blogging-for-next-year thing a few weeks ago; the response in the past few weeks has been nothing but vigorous reinforcement of that perception. I tried to convince myself otherwise by going through the open and moving-towards-approval lang RFCs yesterday, looking for signs of a willingness to say no, to draw lines, to place limits .. and only found further reinforcement of the pattern of addition. Given the willingness on display to take on features, I can't avoid the conclusion that the language team has a serious divergence in direction from .. well, at least where I personally think it ought to be going if it's to retain a decent margin of safety from limits to engineering and cognition. Now, my opinions don't matter that much; maybe I'm old and obsolete and dramatically less-clever than the typical rust user or maintainer and so I'm yelling about nothing. But the issue is that given the number of other people who've mentioned observing and disagreeing with this same pattern, I am concerned that the broader community or org does not seem to have the capability to address a divergence of opinion about where and how to wrap up the language within itself.

The fact that you refer to comments like "saving rust from the lang team" as toxic is perhaps fair from a quality-of-discourse perspective -- snark escalates, and deep personal differences ought to be de-escalated if they're ever to be resolved -- but it nevertheless embodies a sentiment that is clearly felt by a large contingent of the community. I would have hoped there was some less-public, less-critical, less-intrusive way to make this point (I thought a solicited blog response might be adequate) but it seems all that has provoked is denial or insistence that the endless supply of motives for change (papercuts, ergonomics, expressivity, consistency, generality) subjectively outweigh the motives for cessation thereof, without an effort to recognize, reflect-on and resolve the large evident divergence of opinion about where the language ought to be stopping.

I agree this is deriving from a major difference of subjective opinions, and that embedding that discussion in a discussion about LL(k) muddies the water a fair bit. I'm truly sorry to be bringing this up here and now; it's a canonical example but hardly a significant one. But I don't think that observation means that the divergence in opinion is solved (it will not be, regardless of the fate of this PR), nor that the broader guidance of the central shared technical artifact that everyone has to live with should thereby now-and-always go to with the current language team's preference for addition if a big chunk of the community is indicating significant personal-subjective disagreement with that preference. The inability to address such a division is indicative of a governance problem and I hate to be the person bringing that up, but it really seems to me that there is one here.

@pcwalton

This comment has been minimized.

Copy link
Contributor

pcwalton commented Jan 12, 2019

Every time I encounter the need arise for an arbitrary numerical limit, I see a big red flag, spelling out "hack".

But the turbofish is itself a hack. So it's a question of which hack is better.

Here's another example of this that I don't think has been mentioned: I work on a C++ IDE, and doing a full parse of the user's file often takes way too long. (I believe much of this is due to implementation, rather than language, but often that's just reality- e.g. this also applies to the RLS.) So for some operations, we have to find ways to skip things or jump in in the middle- and having the ability to use a more powerful parser than required by a successful straight-line compile is very useful here. (And before you bring up the lexer hack, it does not increase the class of grammar we use in a straight-line compile, and it's not what we're working around here....)

There are real benchmarks provided in this thread. I think those are far more relevant than experiences with C++, which is a completely different language with far more parsing problems than the complexity class of the grammar.

@pcwalton

This comment has been minimized.

Copy link
Contributor

pcwalton commented Jan 12, 2019

@graydon The fact that this is spiraling into a discussion about governance is disconcerting to me. To be frank, it's hard to read this as anything other than a wish to return to the days of you as BDFL. Rust just does not have that model anymore, and hasn't for years.

@H2CO3

This comment has been minimized.

Copy link

H2CO3 commented Jan 12, 2019

But the turbofish is itself a hack.

I get your point, and then we just disagree here. The reason why I don't see the turbofish as a hack is that it's a very simple way of completely eliminating a problem that has been present (and a pain point) in older languages. Given the circumstances, I would even call it elegant compared to other solutions. (And now I'm expecting the stones to be thrown.)

So it's a question of which hack is better.

So, if we regard the turbofish as a hack, then it's the smaller one, because it's local, ie. it doesn't have any other side effect outside its immediate scope.

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Jan 12, 2019

it's clear evidence to me that the chorus of "please stop changing things" input from the community is being flatly ignored by the language team.

Speaking as a member of the language team: no, it isn't. We're actively discussing such things, trying to find new processes, and in any case saying no quite often. Half the things you commented on in your commenting spree were those we had already decided against, or had not yet decided on and were leaning against. That they haven't yet been closed is not an indication that they're moving forward.

Yes, some improvement is needed. In particular, there was a spree of "ergonomics" RFCs that (in my opinion) didn't use the right criteria for evaluating the overall impact on the language. But I feel that that has slowed down, and we're cleaning up the result and trying to make sure the default answer is "no" without strong rationale.

That said, this RFC hardly seems like an example of "we're making the language more complicated"; on the contrary, this change makes it simpler and more consistent.

@rpjohnst

This comment has been minimized.

Copy link

rpjohnst commented Jan 12, 2019

There are real benchmarks provided in this thread.

My comment wasn't about the speed of parsing, so those benchmarks are mostly unrelated. It was about what we did after the implementation-related slowness- which Rust also has, and thus might also need to work around in similar ways.

That said, this RFC hardly seems like an example of "we're making the language more complicated"; on the contrary, this change makes it simpler and more consistent.

That's the main point of contention here. I personally think the opposite.

@pcwalton

This comment has been minimized.

Copy link
Contributor

pcwalton commented Jan 12, 2019

I think it's obviously quite unlikely that this PR is going to be merged, and that's a success of the governance model, not a failure. There was a FCP, the community weighed in with "wait, we don't like this" after it went around on Twitter, and so now it's not going to happen. What's the problem?

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Jan 12, 2019

@pcwalton

I think it's obviously quite unlikely that this PR is going to be merged

I'm curious where you're getting the "obviously" from.

@skade

This comment has been minimized.

Copy link

skade commented Jan 12, 2019

@pcwalton I hate to say it, but, as a project member, I see @graydon's point. It's neither the first time he's voicing it, nor is he the only person who is raising it. There have been multiple calls for stability in the ongoing 2019 blog campaign and I do know that some people approach Graydon with things that they don't feel that the current project staffing could deal with.

There's a growing feeling that I notice on multiple occasions that people don't believe their input matters, and large resources being spent on multiple tries to remove the turbofish are an instance of that problem. I want to add that this is not necessary my opinion, but that doesn't make the feeling go away.

I would hope those issues would be pointed to the community team more, but what I can definitely say is the community team is also internally not consulted on things like this, though assessment of situations like this is definitely our expertise.

I know it's frustrating that generally small things spark these kinds of discussions, but here we are.

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Jan 12, 2019

@skade

There have been multiple calls for stability in the ongoing 2019 blog campaign

I've read many of those blog posts, and I agree. (Some of them are more constructive than others, but the sentiment is clear.) I feel the same way myself.

@graydon

This comment has been minimized.

Copy link

graydon commented Jan 12, 2019

a wish to return to the days of you as BDFL

@pcwalton First: I never asked to be and never was (and strenuously resisted) any title like that when I was "de facto tech lead" inside a team at moz. I regularly lost arguments to you, Niko, Dave, Marijn, Brian and numerous community members, managers and even interns. You're misrepresenting my tenure by using a term like that.

Second: those were some of the hardest and worst days of my life and I wouldn't take the job of even de facto tech lead of this project again if you paid me a fortune for it. If you think I have any nostalgia for that time, you are profoundly misunderstanding me.

I'm disappointed and hurt by this statement, and surprised that you'd even say it, given the circumstances of my departure.

@Manishearth

This comment has been minimized.

Copy link
Member

Manishearth commented Jan 12, 2019

@graydon

I agree, and I don't want to be making pointless arguments in bad faith or anything

to be clear, I wasn't saying that was the case with your comments, it was more of a general "we are heading in this direction and it's good to be aware of it so we save ourselves hours of arguing" 😄

My comment wasn't meant to be a rebuke of anyone, more of just a way to take stock of the state of the discussion.

but it nevertheless embodies a sentiment that is clearly felt by a large contingent of the community

I think there's a good way and a bad way to express the underlying sentiment, I'm not passing judgement on that sentiment itself in the tweet you linked, just the way people typically express that sentiment.

I do think that discussing this and other general governance issues are off topic for this thread, though.

The part of the governance discussion that's relevant to this RFC: it's clear to me that the same governance issues that plagued us during the run up to the edition are rearing their heads again. Given that we no longer have an edition deadline, we don't need to postpone thinking about them so that we can ship things. There have been multiple strong calls for solving "governance debt"/"process debt"/"organizational debt" this year, and it seems likely to me that we're going to decide to focus on that this year. Perhaps we should wait on resolving those first? Default to postponing contentious RFCs that stretch the limits of governance, or something like that.

@graydon

This comment has been minimized.

Copy link

graydon commented Jan 12, 2019

Speaking as a member of the language team: no, it isn't. We're actively discussing such things, trying to find new processes, and in any case saying no quite often

@joshtriplett I'm heartened to hear it, and apologize for the bull-in-china-shop nature of my comments here. This is the last thing I want to be intruding on and I wish I could stay away for good. I'm feeling a bit too emotional about the idea that I'd be wanting to be the governance of the project -- it basically destroyed my life last time I was involved to that extent -- and I hope the divergence I perceive is somehow resolvable. I am not calling for a coup or anything, just some indication of priority being given on acknowledging and responding to the evident gap in opinion. I wish you & the governance system of the project all the luck in resolving the tension here. There have in the past been divisions deep enough lead to people advocating forks; I would love for that to never happen to Rust, but it's only avoidable through conscious compromise, giving up on some of one's wants.

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Jan 12, 2019

@graydon For the record, I do believe you're perceiving a real problem, but it's one that the language team (and other teams) has seen and is dealing with as well.

Speaking specifically for myself at the moment, this is something I deeply care about, and more often than not I find myself the voice of dissent in the direction of "no". :)

@graydon

This comment has been minimized.

Copy link

graydon commented Jan 12, 2019

My comment wasn't meant to be a rebuke of anyone, more of just a way to take stock of the state of the discussion.

@Manishearth I did not read it as such. It seemed an honest and wise assessment. My comment about speaking in bad faith was to indicate that I recognize the risk of speaking that way myself, and that I wish to refrain from doing so.

I do think that discussing this and other general governance issues are off topic for this thread, though

Clear enough. I ought to step away anyways, it's not doing myself or anyone here any further good. Apologies.

@pcwalton

This comment has been minimized.

Copy link
Contributor

pcwalton commented Jan 12, 2019

@graydon I'm sorry. I apologize, that was out of line on my part.

(I had an entire post here typed up, but I think it would probably do more harm than good to litigate this further, especially in this RFC.)

@anp

This comment has been minimized.

Copy link
Member

anp commented Jan 12, 2019

Forgive me for piling on -- I'd also like to quickly apologize for setting a poor tone when I brought this up on Twitter. I could have easily separated out my need to vent from my desire to have a conversation about precedents, and I should have.

Re: this RFC, from @Manishearth:

The part of the governance discussion that's relevant to this RFC: it's clear to me that the same governance issues that plagued us during the run up to the edition are rearing their heads again. Given that we no longer have an edition deadline, we don't need to postpone thinking about them so that we can ship things. There have been multiple strong calls for solving "governance debt"/"process debt"/"organizational debt" this year, and it seems likely to me that we're going to decide to focus on that this year. Perhaps we should wait on resolving those first? Default to postponing contentious RFCs that stretch the limits of governance, or something like that.

The point has been made several times about apparent themes of 2019 posts, specifically how many community members have called for adopting a more conservative stance towards changes to the language. I've waffled quite a bit myself over time, but something has started to happen that's changed my mind a little bit.

Rust is kinda doing really well? Where a necessarily short-term view sees scaling issues, I'm starting to see a really rosy longer-term future as long as we keep figuring the short term stuff out in good faith. If your metric for success is to grow the community and help the world deliver safer, faster software with less work, "scaling problems" translates roughly to "problems due to unexpected levels of success." In no small part thanks to the work of everyone in this thread. It's a sucky side effect of success, but it's still pretty awesome to have it, IMO.

Perhaps this is too generalized, but there's a fun cycle here:

  • more people depend on the language (woo)
  • the community grows (woo)
  • the perceived value of the project increases (woo)
  • the increased importance of getting each change right grows too (hm)
  • the emotional value of "real estate" (RFCs, features, etc) grows too (hmm)
  • the speed of making significant changes slows
  • people perceive the language to be more stable and predictable
  • more organizations depend on the language (oh no, but also woo)

Not sure how to resolve this, but if there's a chance that everyone here has done such important work that Rust is still valuable to the world in 10/20/30?/40??/50??? years, it's worth taking time to get answers to important questions right.

@sayrer

This comment has been minimized.

Copy link

sayrer commented Jan 12, 2019

One alternative I didn't see in the RFC:

Require space around "<" and ">" for comparisons, and prohibit leading and trailing space in generics.

Maybe this is an obvious non-starter, but I thought I would mention it.

@estebank

This comment has been minimized.

Copy link
Contributor

estebank commented Jan 12, 2019

@sayrer right now I can only think of once place in the syntax where whitespace is significant, and thats the nightly-only emplacement syntax, and that is because <- is a valid token, so if x<-1 {} must be written as if x < -1 {}. There's no technical reason it can't be implemented that way, but making whitespace significant can be a similar wart/piece of syntax context that developers will need to keep in mind when writing their code, not dissimilar to the turbofish, although granted, with a lower likelihood of being hit due to the predominant style when writing types, but just as likely to be hit by accident when writing comparisons as emplacement is.

@Ekleog

This comment has been minimized.

Copy link

Ekleog commented Jan 12, 2019

Prohibiting leading and trailing spaces in generics would mean one cannot have a closing > alone on its line, which is currently AFAIR the advised coding style for generics-heavy code.

@sayrer

This comment has been minimized.

Copy link

sayrer commented Jan 12, 2019

@estebank I agree it's a bit of a departure for Rust, but I think rustfmt already does this. One useful pattern for making these changes might be to lift things from rustfmt into the language itself, at the right time. Also, note that the nightly-only emplacement syntax example is a fairly similar issue.

@Ekleog Hmm. I guess only leading space really needs to be prohibited. This seems pretty easy to understand, as it isn't too different from HTML, etc.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Jan 13, 2019

the nightly-only emplacement syntax,

@estebank this was removed from nightly, #2387

EDIT (per @estebank's notes): the feature is no longer active, even in nightly, but the token is still around (which causes this to still be relevant) because of the fallout from rust-lang/rust#48333 [on the wider ecosystem]rust-lang/rust#50832.

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Jan 13, 2019

I think the turbofish is in itself a net negative for Rust - when I learned Rust, the error message did not helpfully suggest turbofish when you tried to use normal braces, so I spent some time unaware that I could specify the type as needed without pulling this expression out into its own let binding. Now, the compiler at least tells you what to do, but its still a stumble and it would be ideal for it to not to be necessary. But I'm wary of complicating the grammar and implementation, and I was optimistic about seeing good, nuanced and precise information about what the costs of removing the turbofish are.

I've gotten the sense this position is pretty roughly the lang team's previous consensus last time we talked about it. In other words, the turbofish is a cost we know, and we'd like to get an accurate weight of the cost we'd be taking on in exchange for it.

Unfortunately, that discussion is not what's emerged on this thread. This thread has become, like so many RFCs these days, full of sound and fury. Exercises like this are unproductive, exhausting, and emotionally draining for everyone involved. This much content, and with this much emotional fervor behind it, overwhelms the projects' processes and grinds other areas to a halt while we all deal with the repercussions of a discussion that erupts in the manner that this has.

I'm not sure what to do about this in the long term, but in an immediate sense I'm calling a cool down on this thread. I'm locking discussion for a couple of days or so and when it gets unlocked I hope it will be conducted with a decorum appropriate to a professional open source project.

@rust-lang rust-lang locked as too heated and limited conversation to collaborators Jan 13, 2019

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Jan 13, 2019

I fear the discussion here is getting way beyond the scope of this RFC. But to add to it anyway: I think it is correct to be concerned about the rate of change, and I know that both the language and core teams think a lot about rate of change. However, I think avoiding change for the sake of avoiding change is as bad as change for the sake of change. Let's focus on the magnitude of the change, as well as the costs and benefits.

IMO, turbofish is a wart. It is not a bad wart, as @skade says, it is easily learnt and infrequently encountered. Nonetheless, it is still something which has to be learnt and is not intuitive. If we can get rid of it, then I see that as making the language less complex for the user. As such it is the kind of 'polishing' change that I would like to see, c.f., change which truly adds something to, or changes the language. I think there is a valid and interesting debate to be add about whether the LL(k) property is an important one to keep. To my mind it is not - it is not the kind of formal category which makes a huge difference (c.f., type soundness, for example) and I think complexity for readers and writers is far more important than complexity for implementers or theoreticians (which is not to say it is not important, just less so).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.