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

proposal: Go 2: remove ++ and -- operators #21263

Closed
bcmills opened this issue Aug 1, 2017 · 15 comments
Closed

proposal: Go 2: remove ++ and -- operators #21263

bcmills opened this issue Aug 1, 2017 · 15 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@bcmills
Copy link
Contributor

bcmills commented Aug 1, 2017

The -- and ++ operators (called IncDec statements in the spec) are confusing for newcomers to the language. In other languages with similar syntax, ++ and -- can appear as either prefix or postfix expressions. However, in Go they can only be used in the postfix position and are statements, not expressions.

In that role, they are completely redundant: += 1 and -= 1 are statements with exactly the same semantics. Perhaps more importantly, += and -= in Go match the semantics of similar operators in other languages.

For comparison:

  • The Swift maintainers had the courage to remove their versions of these operators in Swift 3 — and their operators were even the kind that match pre- and post-decrement operators in established languages, not redundant syntactic sugar.
  • Rust had the foresight to leave them out in the first place.
@gopherbot gopherbot added this to the Proposal milestone Aug 1, 2017
@slrz
Copy link

slrz commented Aug 1, 2017

I don't think the stated benefits are anywhere near convincing enough to pay off for breaking every single Go program in existence (even if go-fix-able). Go 2 doesn't have the luxury of starting from a clean slate where these ideas might be more appropriate. Also, this is not Python.

@bradfitz bradfitz added v2 A language change or incompatible library change LanguageChange labels Aug 1, 2017
@josharian
Copy link
Contributor

I'd miss them in simple counting for loops, just for the reduced line noise. Maybe it's a good idea anyway, but I have a hard time convincing myself that this could be among the top three to five significant language changes that Russ indicated are budgeted for Go 2.

@bcmills
Copy link
Contributor Author

bcmills commented Aug 2, 2017

I'd miss them in simple counting for loops, just for the reduced line noise.

Yeah, I need to write up an experience report about loops one of these days: I'm not convinced that we should keep the three-slot for loop either, but that's a matter for another proposal.

I have a hard time convincing myself that this could be among the top three to five significant language changes

Agreed. It would have to be one of the minor changes, which I think also implies that it couldn't be the only one that requires a go fix. But if we end up needing to go fix most code anyway, it would be a nice change to piggyback.

@bcmills
Copy link
Contributor Author

bcmills commented Aug 2, 2017

It's easy to propose additions to the language, but that's how you end up with a complex behemoth like C++. Where I'm going with this proposal (and #21165) is that I think it's important that we also consider which parts of the language aren't pulling their weight: otherwise, Go 2 with be strictly more complex than Go 1.

(#20446 ("drop new") is along similar lines, but new, unlike ++ and --, isn't entirely redundant today: there is no existing expression that is a drop-in replacement at all call sites.)

@griesemer
Copy link
Contributor

++ and -- are here plainly for convenience. i += 1 is twice as long as i++ in number of characters and a bit more awkward to type.

It would be useful to have some statistics (say, over the std lib) about their use relative to loops and perhaps other operators.

@bcmills
Copy link
Contributor Author

bcmills commented Aug 7, 2017

i += 1 is twice as long as i++ in number of characters and a bit more awkward to type.

@griesemer I am not aware of any other features in Go that exist to save a handful of characters per operation. What is different about these operators that makes them exceptional?

The two closest examples I can think of are:

It would be useful to have some statistics (say, over the std lib) about their use relative to loops and perhaps other operators.

Agreed. In particular, I suspect that we could make most existing uses of ++ and -- even more concise by expanding range loops to work with integer ranges.

@josharian
Copy link
Contributor

https://github.com/josharian/gofor has a crude script and some four-year-old data in the readme. I doubt usage patterns have changed substantially since. I hacked it together long ago in preparation to write a proposal to expand range loops to work with integer ranges. (I ended up not writing it because I perceived it to be pointless, in light of some of Rob's comments on golang-nuts.)

@griesemer
Copy link
Contributor

@bcmills As I said, they are here plainly for convenience (the convenience being that they are shorter and easier to type than the equivalent). When we started with Go there was an (perhaps incorrect) understanding that ++ and -- are frequent and would be widely used (based on past usage in C, of course, where they are also there for convenience). Maybe that convenience is not that important anymore (range came later), and maybe there should be some range support for loops where we currently rely in ++/--. Statistics could shed some light on this.

@dominikh
Copy link
Member

dominikh commented Aug 8, 2017

I find "they're confusing to newcomers" a weak argument. The argument is backed by a link to an FAQ entry that suggests that our operators are confusing because they're less powerful than those in C. Based on that argument, a valid fix would be to make them more complex.

In reality, I don't think that these operators are confusing. People with no solid background in C-like languages can easily learn our definition of the operator, and people who do have said background are more than capable of relearning a small detail in a matter of minutes.

You're correct in pointing out that our version of the operator doesn't have any benefit over using += 1, other than a tiny amount of conciseness, and in isolation, that may be true. Removing the operators, however, would cause a lot of code churn, for IMO no real benefit in return.

Both Rust and Swift started with C-like operators and decided to remove them entirely, as opposed to adopting our definition. Going from very confusing operator to no operator has much higher payoffs than going from already simple operator to no operator.

@mewmew
Copy link
Contributor

mewmew commented Aug 12, 2017

Rust had the foresight to leave them out in the first place.

From the Rust FAQ:

Preincrement and postincrement (and the decrement equivalents), while convenient, are also fairly complex. They require knowledge of evaluation order, and often lead to subtle bugs and undefined behavior in C and C++. x = x + 1 or x += 1 is only slightly longer, but unambiguous.

The stated reason for avoiding the inclusion in Rust was confusing evaluation order (this seems to apply also for Swift); an issue which Go does not face as increment and decrement statements are not expressions.

I understand my comment is mostly noise, as @dominikh has already pointed this out. Just tried to frame the wording in a different way.

@andlabs
Copy link
Contributor

andlabs commented Sep 9, 2017

This change is the single stupidest thing Swift did. Let's not make the same mistake. It's a shame that the way they work in C has caused people to consider them harmful. But I don't buy the "it's too confusing for newcomers" argument, because a) Go makes them sufficiently different enough, and b) it's incredibly patronizing to assume that something as simple as "this increases x by 1" is too confusing to beginners. I know it's hard for us to do, but we need to not assume that beginners are dumb, and give them some show of confidence. After all, people who use the ++ and -- operators in C and C++ have at least learned how to use them well in 30+ years, to the point that we have useful idioms like *p++ = *q++ that most C/C++ programmers who aren't just starting to learn know what they mean instinctively (and if they are learning, they are almost guaranteed to encounter at some point during learning).

@as
Copy link
Contributor

as commented Sep 9, 2017

Which of these look most confusing to newcomers?

x /= 5
x >>= 5
x <<= 5
x *= 5
x %= 5
x = -x
x = +x
x += +x
x -= -x
x += 1
x -= 1
x++
x--

I think the ++ and -- are fruit hanging a bit too low. Seems like it would annoy more than benefit. Swift removed them from the language, which is a bit different than never having them in the first place.

@andlabs
Copy link
Contributor

andlabs commented Sep 9, 2017

Honestly? <<= and >>= might be the most confusing to beginners (note that I say beginners, not newcomers — newcomers from other languages are likely going to be familiar with all of that, including ++), because they may not yet have the understanding of binary arithmetic; by comparison, it isn't hard to understand "this is shorthand for adding 1 to x".

@pciet
Copy link
Contributor

pciet commented Jan 17, 2018

Despite using these regularly I’d be ok with writing out x = x + 1.

// seems fine to me
for i := 0; i < len(a); i += 1 {

These operators are one more thing for new programmers to learn. We don't need them.

@ianlancetaylor
Copy link
Contributor

The benefits are not worth the drawbacks. While there are supporters, there are more detractors. Closing.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests