248 comments

[ 3.0 ms ] story [ 207 ms ] thread
> Their expressive advantage is minimal - x++ is not much shorter than x += 1

Personal opinion, but I definitely miss '++' every time I'm doing '+=' in Python.

I think I'd argue with the "not much shorter" because it's less typing to perform a `++` versus `+=1`; I hold shift, I type the = key, obtaining the +, then I have to pause typing long enough to release the shift key, type the = key again, and now my other hand has to get involved and type a 1. And that's without the spaces.
Typing is not the bottleneck.
Yes, typing is indeed the bottleneck. Perhaps it doesn't add up to much time overall, but until we get brain-computer interfaces and the ability to will code or instructions into existence, I want every barrier to moving the solution from my head into the computer as small as possible.

I had a very similar conversation with a colleague about UX. This one operation might not happen often, but when it does, it should be intuitive and fast. The technology is here to serve the humans.

My point is just that a programmer spends a lot more time thinking about the problem domain; how to approach a particular problem; what patterns he might use; and details about the particular solution they've chosen, than he does typing.

That is, if you're optimizing typing, you're optimizing the wrong thing, and if you want to improve your ability to write software, you should instead be getting better at these other things. The typing part is good enough.

Edit: Or if typing really is the bottleneck, you're a much better programmer than me.

Well, I type the * key to get a +, then shift and 0 to get a =, then 1 to get a 1.

Slow, and my fingers have to jump completely over the keyboard.

What is far more annoying, and should be banned, are `these` (I have to press shift+' twice to get one `, otherwise I end up with á' instead of `a`), and {}[], as they are on AltGr+7/8/9/0

Which type of keyboard do you use? I know English-International has a similar issue with `'`, `"`, and `'`. I think QWERTZ or a German keyboard do as well? Can try changing it to English - US to get around that if you run Windows. Not sure about Mac/Linux.

I swapped the US out for international because it was important to me to type Pokémon properly. It is an annoyance to have to type ` followed by a space because it is waiting for a vowel to let me type ù. Same with ' which let's me type ç or " which lets me type ü... etc. I disable it when programming for the reason you cited. It can be annoying to deal with. Especially when my IDE tries to autocomplete " and I typed "" instead of " (followed by a space) and I get """".

I use a bastardized DE1 layout, as provided by linux.

So I have æ, but not å.

Actually, I’m gonna switch to DE3.

Still doesn’t solve these special characters.

I guessed the German QWERTZ properly at least...unfortunately I don't know a way of solving that without having an EN keyboard, using a keybind to swap between T1/EN as needed. Though depending how much German shows up in your programming... swapping every few characters probably isn't desirable either. :(
I write literally no German in code, but sometimes use it online.

And I seriously couldn’t work without the international layout - using proper Unicode characters in my comments is just non-negotiable.

If developers would have thought more about localization, and made less dumb assumptions...

But there are even minecraft mods that don’t work on QWERTZ, because they are hardcoded to keys that are dead keys on DE layout.

I press alt+shift and can switch between EN-International (which allows easy typing of é, è, ç, etc.) and EN-US (which doesn't easily allow them to be typed).

Therefore in EN I can {code} and then alt+shift and {comment with proper Unicode characters}. My suggestion would be to have a setup of T1/EN. Code in EN and comment in T1.

Sorry if I'm not being clear or if I'm being confusing...

>If developers would have thought more about localization, and made less dumb assumptions...

I18N can be time-consuming. Especially to test on every conceivable keyboard layout. Dumb assumption allows the mod to exist. I'm all in favor of I18N (and help translate things when I can!) but honestly it is a lot more work for what is often very little gains.

Would you rather spend 10 hours adding I18N for 100~ players or spend 10 hours improving the rest of the code base and adding new features for 10,000 players? Most devs choose the latter. Which really sucks if you're in the group of 100~ players.

Well, I actually modded the mod myself – and just made it use Minecrafts' integrated keybind tool.

And switch EN and T1 is not very useful. I’d have to relearn blind typing completely again.

cant you use `+space to type one? it always worked for me with all keymaps... was awkward the first few times, but by now its become really easy.
Yes – but that’s still [Shift]+['] and then [Space]
If typing is the bottleneck in your development you're not solving difficult problems and could probably make more money solving difficult problems at a different job.
(comment deleted)
I think forcing me to use "+=" in Ruby reminds me that it's really a method call (which can be overridden), rather than an increment operation on primitive types.
Yes, this exactly! While rarely a good idea, it does give you super powers when dealing with specialized libraries, or when writing your own :)
Have you ever written a container (with an iterator)?
And yet, ruby still provides 4 unary operators that can be redefined.
++ and -- (both versions of each) would end up being method calls as well in Ruby or Python. They're even overridable in C++.
I do too, but it's worth it to not have x++ and ++x thrown around inside of expression bodies (especially while loop conditions).
Agreed. In the list of disadvantages, we don't see "many professional programmers expect the ++ and -- operator" or "beginners will be confused because old code examples on the web will stop working".
This argument feels like 'legacy for legacy's sake'.
Frankly I think discussions like these show how not all programmers are engineers. Cutting down on complexity and ambiguity is a good thing. Because even if you can handle something, when you have teams of 100+ people with 100 000+ lines of codes, all those potentials for errors quickly adds up.
Which is actually quite common. Unicode is ASCII compatible and on Windows you still have to do carriage return before a line feed, although there are no teleprinters involved.
Which wipes out the "easier to learn as a first language" point, and then some. Copy-pasting code from stack or somesuch only to have it not work and not know why is incredibly frustrating for a beginning programmer. I certainly found that with wpgtr back in the day.
Then I take it you don't buy into the Python philosophy of "There should be one-- and preferably only one --obvious way to do it."

https://www.python.org/dev/peps/pep-0020/

To me, ++ is the one obvious way to increment. I use for loops constantly and think of incrementation as a different thing from addition.
To be clear, do you mean ++i or i++?
Well yes, they are different from addition, but that still doesn't justify a special symbol for a special case of addition.

When your "increment by 1" is really just in the service of iterating over a set, then the natural, obvious way should be to use a separate idiom that abstracts the concept of iteration over that set, rather than dive into the details of how you get access to the next member. Which is what Python does: "for x in ...".

If the loop is not simply iterating over the set, but tweaking some value unpredictably and periodically checking, then there's nothing special about += 1 relative to += 2.

Why are you incrementing inside a Python for-loop? Are you familiar with ``enumerate``? In most situations, Python provides an iterator that tracks state for you and it's not necessary to increment state explicitly in the loop.
In higher level languages, loops are not about incrementing.
Neither does Python. For example, % operator and .format().
I did miss it too, for the first 2 weeks I started using python. After that it just seems ugly.
I've always felt like Python and Ruby chose to drop these to discourage you from writing traditional loops, as they have their own enumerators to accomplish the same thing. And, as the author mentioned, so does Swift. Obviously you still have to do a '+=' occasionally, but I don't find myself doing that often.
Yeah, I think the core difference between i++ and i+=1 (expression vs statemrnt) is mainly useful in situations where higher level structures are available in languages that aren't C
post increment/decrement is definately worth removing imo.

so few people understand its behaviour and it enables some really revolting and difficult to read things. i think a lot of people learned this in the 80s, 90s and 00s even... its not a new revelation.

the pre-increment/decrement though? i think having these is important. there are plenty of contexts away from numbers where they make sense (things can be ordered and not have a concept of addition)

What about a function named succ or next? They would make things a bit more explicit, and succ has its own tradition.
Those exist, as part of "RandomAccessIndexType", to which "Int" conforms:

1.advancedBy(1) == 2

This is different than ++, though, because ++ mutates the value, and advancedBy(:) returns a new one.

true. although we would call it successor right?

shortening function names with abbreviations ought to have died when fortran relaxed that restriction. XD

> it enables some really revolting and difficult to read things.

for others, though, it really enables the writing and reading of some very elegant and concise code.

usually when people say this what they mean is revolting and difficult to read things.

(i'm not 100% sure this means you, but all of my experience tells me this is likely the case, sorry to have to be critical)

i've heard this sort of thing about

  *a++ = *b++;
and variants thereof, which is the classic example of this.

a lot of the times i have seen this stuff it is in the middle of even more revolting code too... like some 1000 line function (which could be 10 functions and has comments inside of it that delineate the obvious splits) with a gigantic switch statement (which could be a class, or in C a function pointer), containing loops, where there are 20 lines like the above but even more difficult to read in a row (which could have been a nested loop with identical logic referring to some constant data) - to think of the most recent example i faced.

sadly i've seen this sort of stuff so many times for so long that i find it easy to read, but it is intrinsically difficult involving precedence and the post-increment gotcha, and it gets worse if there is even more being done than just a straight copy.

Why not leave those operators for more "advanced" users?

I also contest "++" and "--" operators are seriously tripping up "beginners". In most programming books, it's taught a few chapters in...

Because non-advanced users will incorrectly abuse them. That's why ARC doesn't let you call retain and release manually, even though there's no technical reason it couldn't.
> Because non-advanced users will incorrectly abuse them.

I don't see how this is a valid reason to remove the operators completely. Beginners will get it wrong sometimes, so we should remove it?

Beginning users are likely to make all kinds of errors, so the implication would be maybe we should remove the entire language...?

Not to mention, pre-decrement and post-decrement are not complicated concepts. There are many valid reasons to use both, although post-increment/decrement seems to be the more common use.

Well, the same argument can be made for pointers, which are clearly harmful to a safe language.

Swift does include them, but puts a screaming "Unsafe" in front of their type names so that it's clear that unless you really know what you're doing, you're probably doing something wrong.

There's no way to do that with a ++ operator, so it's being removed.

Do really think the complexity of pre/post-in/decrement is on the same level as pointers?
I think the added complexity to added value ratio is worse for pre/post-in/decrement operators than it is for pointers, even if the added complexity is less.
Yes - or in the Apple ecosystem, method swizzling is incredibly useful but also incredibly harmful - both to performance through necessitating dynamic dispatch, and to confusion, because WTF, method swizzling?
(comment deleted)
I didn't know we were making comparisons between Swift and C.

Most people would agree C lets the developer do a lot of terrible things (by design, since some of those terrible things are necessary for low level stuff, which C was targeted at).

Pointers are confusing for a lot of people. Which is why almost no modern language uses them. Comparing "++" with C pointers is not a valid argument.

Even so, I would never argue to remove pointers from C, since you can optionally not use them. If you don't need that language construct in your program, don't use it. But leave it for others who do want/need it.

This operator was popularized by C, so comparisons with C make sense. Of course you wouldn't remove pointers from C, the language would barely work if you did.

Confusing C-isms like pointers are what Swift is trying to get away from. This is another case of that.

"We're making a new language, it isn't C, but will share some characteristics. Which should those be?" is the question being asked here.

It seems to me, we're trying to make Swift "beginner-proof".

The problem, Swift is unlikely to be a "beginner's language"... since it's predominantly (at least for now) an Apple language; used almost exclusively for making iOS apps.

To make an iOS app, you have to have an Apple Developer license, be paid up on fees, own a very expensive Mac, and pay Apple to put your app in the store.

None of which is something a beginner, just starting to learn programming, is likely to do.

It's less beginner-proof, and more "doing bad things proof". The purpose of releasing Swift as open source is that they don't want it to be an Apple language. I can't wait for it to replace Python for scripting - I dread every time I'm writing code without a competent type system.

> be paid up on fees

This isn't true anymore, FWIW. Also, OS X apps exist.

So? Advanced developers abuse languages all the time. This isn't a valid argument.
Making the language difficult for advanced developers to abuse is practically an explicit goal of Swift.

I mean, its predecessor allowed you to mutate your class hierarchy at runtime, and this was a thing that people commonly did!

"You can't do that" is a powerful tool for making code safer.

Because they can constrain the design of the language, and make it more complex to reason about the language. Look at the language necessary to explain their pitfalls in the C standard, or the extra copy needed in operator++(int) to support post semantics in C++.

They also make the tools that consume that language slightly more complex. It doesn't sound like much, but in aggregate it's the difference between writing a parser for Java vs. a parser for C++.

Reading is more important than writing. If you leave them in they're one more special case that everyone has to memorize before they can maintain someone else's code.
> If you leave them in they're one more special case that everyone has to memorize before they can maintain someone else's code

It's literally no different than having to remember what "+=" does... which is what's being proposed as the alternative.

> Reading is more important than writing

I would agree, but "x++" is not difficult to read. It's more concise than having to read "x += 1". Or worse, beginners will think it's clever to define constants for this so now you'll get "x += INCREMENT_VALUE", making you have to go lookup whatever "INCREMENT_VALUE" is, etc...

> It's literally no different than having to remember what "+=" does... which is what's being proposed as the alternative.

You already have to remember what "+=" does though. If they kept ++ you'd have to learn both.

I don't get the argument... you have to learn what "+" does, so why not remove that and just have "-" since you can subtract negative numbers to add. The line of reasoning that it is more to learn is ridiculous. The concept of incrementing or decrementing a value is trivial. If "++" seriously trips you up as you learn to program, perhaps programming isn't for you...

"+=" is no better.

If you're going to campaign against "++", might as well go all the way back to BASIC days and only allow "x = x + 1"

x = x + 1 isn't so fun when you're writing

    long_variable_name = long_variable_name + 1
That's the problem being solved in a modern language. The ++ and -- operators don't add much. They're the perfect a combination of rare, unnecessary, and often ambiguous. Not to mention that their semantics are often different in subtle ways between languages.
`lon[tab] = lon[tab] + 1`

Autocompletion is a wonderful tool that every developer should use, if only to reduce the possibility of `long_variable_name = long_varable_name + 1` in their code.

>If "++" seriously trips you up as you learn to program, perhaps programming isn't for you...

And by induction you can use this argument to allow any amount of bullshit in a language.

>"+=" is no better.

"+= x" saves you from "= long_variable_name + x" which is arguably less readable.

"++" saves you from ... "+= 1" which is already entirely clear, and I have no idea why anyone feels the need to shorten it.

Sure it's a relatively small complexity cost, but it's also an even more microscopic advantage.

> you have to learn what "+" does, so why not remove that and just have "-" since you can subtract negative numbers to add.

Because "-" is part of the domain language (mathematics).

> The concept of incrementing or decrementing a value is trivial.

For a normal function (i.e. something that could be implemented as library functionality) then I agree with you. But for a language-level operator, it's a special case. It probably has its own precedence. It definitely complicates the metamodel.

> If you're going to campaign against "++", might as well go all the way back to BASIC days and only allow "x = x + 1"

I would. How many times do you need to add 1 to something anyway?

Because beginners could get confused when seeing the operators in other people's code, for example.

I remember the day I first saw a '++'. It was a rainy night, and I was inspecting a colleague's for loop, when suddenly a '++' operator appeared. I asked myself, "What in the holy bacon of Zeus is that?" So I looked it up in my book. My head almost exploded, and I asked myself if I should quit programming immediately. It was simply too complicated. After four months of agony and pain I finally recovered and started programming again. And yet... Sometimes, when it's raining outside, the memories come back. Programming... No, my life will never be the same again.

I'd hate to think what would happen if one were to run into a ternary operator!
I've never understood the obsession with avoiding ++ and --. Douglas Crockford advocates the same thing. All of the examples of why it's bad are contrived and set up to fail. In the majority of real world instances, it's just us incrementing or decrementing a single variable.
In Go, where they're a statement, they're fine. But as an expression, but stuff can happen. In non-contrived, real-world, historical examples.
Was just thinking in moldy old c code the two places to use ++ or -- was when either incrementing pointers or indexes.

The other is ++ and -- also map directly to old school assembly language instructions. Helpful when writing the back end of old school compilers.

Probably doesn't make much sense in a language with foreach() or dictionaries, etc.

All the examples where they're useful are contrived.

And simplicity is an actual goal of computer language design.

That's quite a claim. I agree that most uses of these operators as an expression are not wise. Some are though. As a counter-claim, I offer:

  array[i++] = this;
  array[i++] = that;
  array[i++] = the_other;
which also extends nicely when some of those elements are optional.
For what it's worth, you could always make a function postincr and write

    array[postincr(&i)] = ...;
if you're doing enough of those that it's worth it.
I presume you're using C as the example language?

Most modern languages have an append-to-list method/function, so your example isn't really applicable in those langauges. For example, ArrayList#add() for Java or Vec::push[1] for Rust, etc. (Yes, these are technically dynamically sized arrays, but you can always reserve the necessary amount of space up front if you so desire.)

[1] https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pus...

Doing stuff because that's the way C does it is a surefire route to unintentional autoemasculation.
Doing stuff because that's the way elisp does it is a surefire route to unintentional autoemacsulation.
While 4 touches on this a bit, I think another reason is that mutable value types are generally harmful. Save mutability for compiler optimizations and write your code with "let".
You need mutability to write for loops.
C-style for loops are discouraged in good Swift code. Use map, ranges, or for/in instead.
So.. get rid of 'x += 1' as well?
Yes! And local "var".

The optimizations that "var" allows should be the job of the compiler.

It's still needed at the non-local level on reference types, but could possibly be disallowed in structs as well.

Go’s compromise here is that these operators are statements, not expressions. There is no return value. This makes it semantically identical to i += 1. It keeps some sugar while removing some classes of gotcha.
Just having `i += 1` would seem more in line with Go's professed Simplicity philosophy. When both `++i` and `i += 1` mean the same thing, you might as well drop one of them. `++i` (and/or I guess `i++`) is barely syntactic sugar.
i++ is different from i += 1 in this way: += could be i += 2 or i += j or something else. I have to pay attention to be sure. But i++ can only add one.
Yes, you actually have to read the statement `i += 1` in order to know what it does. I don't see how that is an argument. It's barely longer than `i++`, in any case.

I could buy the argument if we were dealing with indexes or numbers where you had to read/hunt down occurrences of them to make sure they are what you expect. Like: make sure that a loop with a lot of indexes don't overincrement (out of bounds) or does something else that is wrong. But in this case the space isn't across a method, or a block. The space between the destination (i) and the increment number (1) is literally just 4 characters.

But the point is that with ++, I don't have to look at all at the increment - I know what it is. The issue isn't how far away I have to look, it's that I have to look at all. (Or I don't look, and just assume that it's an add-one because that's what it always is, and then wonder why my loop doesn't work right.)
> the point is that with ++, I don't have to look at all at the increment

Of course you do, otherwise you wouldn't know it was an increment in the first place.

Well, all right, my brain has to parse one fewer symbols. ++ is the equivalent of parsing +=, but there's no "1" or "j" or anything else that I have to parse in addition.

(No pun intended, but I also didn't edit it out...)

> (Or I don't look, and just assume that it's an add-one because that's what it always is, and then wonder why my loop doesn't work right.)

How often do your loops depend on incrementing a variable by one? In _Swift_ code.

>Yes, you actually have to read the statement `i += 1` in order to know what it does.

Beginner here. Small detail...

`i++` is read as `i = i + 1` and not `i += 1`. A small, but important distinction, especially for a beginner. `i += 1` is also parsed as `i = i + 1`.

However for `i += n` it no longer parses as `i = i + 1` but rather `i = i + n` which is a step more difficult (and more powerful) than i++ which is always `i = i + 1`. However that is additional complexity not found in `i++`.

(This is why I found `i++` easier than `i += 1`)

FWIW, Go linter suggestion is to to use i++ but i += 2. If you write i += 1, it'll suggest you should write i++ instead:

    main.go:6:2: should replace i += 1 with i++
That said, if it were removed, I'd probably be happy because it makes the language a little simpler, but I don't mind having it too much either, because it's a statement rather than an expression.
wow, now that seems needlessly confusing. "use x += _" to increase x by any amount except one, in which case you use x++"
+= 1 is a pretty common case though, it doesn't seem particularly arbitrary for it to be special. It's not "clean" or "minimal" but it is pretty convenient.
Agree they could have done without it entirely.
Good. I've always presumed ++ is in C because processors had an increment instruction that was faster than add back then, and for the PDP-11's autoincrement addressing mode. Presumably Dennis' compiler would have been that much bigger in order to spot these optimizations vs having the programmer explicitly invoke them -- perhaps big enough to no longer fit in memory.
People suppose this, but that's not quite how it happened. C came from B, and B had ++ also. But B came before the PDP-11. The PDP-7 had hardware that supported auto-increment-by-one, and Ritchie suggests that's where ++ came from.

The PDP-7 assembler manual is at http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp7/PD..., but I can't see any reference to this auto-increment hardware, or to an assembler directive using it. What I'm getting at is that there appears not to have been an assembly language construct for auto-increment on the PDP-7 at all, even though its hardware supported it.

The hardware "auto-indexing" is described at page 3-12 of the PDP-7 architecture document, http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp7/F-... . It is enabled only for about 8 special memory addresses in each 8K of address space, so it is weird and handicapped by comparison with the PDP-11.

See Ritchie's history (http://www.bell-labs.com/usr/dmr/www/chist.html) --

"Thompson went a step further by inventing the ++ and -- operators, which increment or decrement; their prefix or postfix position determines whether the alteration occurs before or after noting the value of the operand. They were not in the earliest versions of B, but appeared along the way. People often guess that they were created to use the auto-increment and auto-decrement address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is historically impossible, since there was no PDP-11 when B was developed.

"The PDP-7, however, did have a few `auto-increment' memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own. Indeed, the auto-increment cells were not used directly in implementation of the operators, and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1."

Very interesting. I have supposed this since using PDP-11 assembler and reading Dennis' compiler in the late 70's.

There were machines with auto increment modes long before the PDP-11 though, e.g. "http://ed-thelen.org/comp-hist/GE-635.html#Indirect Then Tally (IT) Modification"

I hear you. I learned assembler on the PDP-11 -- a delightful memory -- and had the same misconception until I read Ritchie's piece.
Is this like the Apple idea to have a 1-button mouse? I like to ++ things, because when I'm coding, it fits better with that focused efficient state of mind where you don't have to think about x + 1, you just say ++ and it's bigger. But I'm not an Apple programmer, so maybe this isn't for my style.
> Their expressive advantage is minimal - x++ is not much shorter than x += 1.

And there is no ++ equivalent of x += 2.

Yes. Anointing "+ 1" as a thing that needs special syntax is weird.
> Yes. Anointing "+ 1" as a thing that needs special syntax is weird.

Its not a special syntax for "+1", its a special syntax for the combination of assignment and increment/decrement.

The postfix versions (increment/decrement variable and then return the value that was present before the increment/decrement), particularly, are equivalent to:

  _x = x; x += 1; _x
In an environment where that pattern of operations is common, I can see the value of having a concise mechanism for expressing it.

OTOH, there's a cost to it, too, and I'm mostly happier without them around.

Sorry, you are correct - although I would restate my point with "+= 1" isn't special.

1 is just another number, the fact that it's useful for enumerating arrays in C isn't relevant as Swift provides more native solutions for that, the use of which should be encouraged.

Have you never heard the rule that your code should have no numbers in it except 0 and 1? All other numbers should be written as constants instead, and then use the name of the constant instead of the number directly.

> Anointing "+ 1" as a thing that needs special syntax is weird.

1 is special.

Yes, of course, I use constants in all cases.

Why is adding 1 to something special, compared to adding 2 to something? The #1 use case, by far, is C-style for loops, which aren't used in idiomatic Swift code.

I said why: The 2 should be a constant as a name, but the 1 can be a bare 1.
Not necessarily so if you come from a strong Assembly language background. Most processors have a special instruction for incrementing a register that's shorter (and faster) than the more generic ADD instruction.

For instance, on a 64-bit x86 machine,

    ADD RAX,1
is nine bytes long, while

    INC RAX
is one byte. Maybe not as much a win these days, but back when memory was smaller and more expensive, it was worth it.
In a high-level language, this is the job of the compiler, though. If the compiler isn't generating those instructions for cases where the increment can be proven to be 1, I would consider it a bug.
Nowadays, a compiler that doesn't optimize a "+1" is a bad compiler.
These days yes. But when C was first being developed, when you might have had 64K of memory for everything? Back then it might have been a sane choice.
Doesn't x86 machine code have short-immediate forms? So ADD RAX,1 could be 4 or 5 bytes. Still a win to use INC of course.
Any optimising compiler for a mainstream language that can't do this optimisation reliably in this day and age is crap.
Compiling

  #include <stdint.h>
  uint64_t inc(uint64_t x) { return x + 1; }
With -O0 gives me:

  48 83 c0 01          	add    $0x1,%rax
and with -O2:

  48 8d 47 01          	lea    0x1(%rdi),%rax
That is, both are four bytes.
I'd say the expressive advantage of x += 1 is zero since it's not an expression.
Perl 6 user defined operators are just made to order for you.
"Drop one of x++ or ++x. C++ programmers generally prefer the prefix forms, but everyone else generally prefers the postfix forms. Dropping either one would be a significant deviation from C."

Funny given the name of the language.

C++ is not even a good increment of C. Yes it had a lot of inspiration from C, but in all seriousness, it should not have been called C++ since it is not backwards compatible with C without some serious work. Honestly longest running ironic language name.
Sorry, the lifetime winner of that award is JavaScript.
Actually it's a good name. C got incremented, and we keep original C locally while some weird side effects no one really wanted keeps happening in committee until the end of time.
VOTES--

MORE SERIOUSLY....CODING CAN BE ABOUT AESTHETICS. YES, JUST BECAUSE. CODE CAN LOOK GOOD AND THAT IS A VALUE.

BUT ALSO, AESTHETICS CAN HAVE A NON-MEANINGLESS AFFECT ON COMPREHENSION, READABILITY, CODING-PLEASURE AND PRODUCTIVITY. SO MONEY, BASICALLY.

PERSONALLY, I LOVE THE ++ AND -- AESTHETIC. IT'S JUST A COOL GLYPH/DIGRAM/IDIOM. BRING BACK THE QUIRKINESS ( OKAY, NOT TO THE PERL-LEVEL ) BUT BRING IT BACK!

Judging by your capitalization, you must be of the BASIC school of aesthetics...?
It could be FORTH.
Or PHP, if they're one of those very few people who still writes it like that.
Is this some kind of troll/satire on aesthetics?
I strongly disagree with this. Being able to do a very simple task like increment or decrement a number inline is useful and reduces clutter and I've always found the idea that the operator complicates things ridiculous. The way they work has always been obvious to me since I first learned to program in PHP as a tween.
"These operators increase the burden to learn Swift as a first programming language"

It looks like they may be trying to make it easier for current tweens that would have otherwise learned PHP.

Don't see the value in this. These operators are terse, well known, and are implemented in a wide array of languages.

Well known for old timers. But some folks have an actual issue understanding them. For those of us that are comfortable; fine, no issue. But they are a little strange; the order of operations in a complex expression can be hard to tease out for novices. Are they worth it?
What about for beginners like me who instantly understood `++` and `--` as increment/decrement but avoided `+=` and `-=` for being rather nonsensical?

This half-reeks of something that a professional/advanced user thinks trips up beginners without actually tripping up beginners. Or they have an anecdotal sample size of n < 10 and decided since it confused 1 person that 10% of people get confused.

Apple has a long history of readability over terseness.

"plus plus" doesn't mean anything. It might even be confusing that it doesn't add 2.

From Swift documentation:

for i in 0..<count { print("Person \(i + 1) is called \(names[i])") }

This ..< operator is so much more logical, of course! Not to mention == and ===. Logically, the first one compares twice and the second compares three times (for luck), just in case first two comparisons didn't go through...

(comment deleted)
I would implement that like:

    zip(names, 1...names.count).forEach { name, index in
        print("Person \(index) is called \(name)")
    }
Or, in an ideal world:

    zip(names, 1...names.count)
        .map({ name, index in "Person \(index) is called \(name)" })
        .forEach(print)
Currently, that isn't valid Swift, "print" can't be used like that, though if you define a closure it works:

    let printIt = { x in print(x) }
    
    zip(names, 1...names.count)
        .map({ name, index in "Person \(index) is called \(name)" })
        .forEach(printIt)
I think that Swift could use = for equality, since assignments return Void and comparison returns Bool. Maybe it should.

But your argument boils down to "if you can't be clear everywhere, don't be clear anywhere". That's not a good goal.

My argument ultimately "there are better things to do". At the same time, interpreting ++ as add-add is certainly not an argument. You can say that you don't like infix and postfix operators, but not whether they are readable.

If you consider readability, then why !a instead of not(a)? Why || instead of or?

Speaking as somebody who has no idea what X..<Y means, I assume it means "start from X and carry on for as long as you are less-than Y"? Is that correct?

I wonder what somebody who had no idea about X++ would guess it meant? Based on my daily conversations, if I didn't know already, I would guess it means "variable X has done a good job and deserves some IRC karma"...

What's an IRC? What's a variable? :)

Look, don't get me wrong, I applaud the intent to make the language easy for total beginners. I argue that it's a longer stretch to understand ..< operator than ++.

Arguments like people who never programmed before should be able to use it are great, but one should consider those in the context of the entire grammar, not just one operator.

In my opinion Swift does not shine here, regardless what Apple says.

Plus a relatively easy concept to understand even if you encounter them for the first time. I'd say that it's even more intuitive than +=.
They're obvious but only after you've learned them (compare it with x// if you saw that for the first time?).

If readability matters then the rationale that x += 1 is more readable than x++ is very reasonable.

  I've always found the idea that the operator complicates things ridiculous
Given that there are interview questions on the behavior of post/pre increment operators shows that there is some subtlety to it which creates ambiguity and complexity. So given that they want the language to be accessible, it makes sense to reduce ambiguity.
There are also interview questions asking you to write FizzBuzz. That doesn't mean all loops are ambiguous and complex.

Being an interview question doesn't really mean anything other than it being an interview question.

Seems more like an idiot test to me. If someone legitimately finds something this basic confusing they are going to constantly be running into problems and aren't suited for a programming job.
++ is a rare situation since the introduction of foreach. For example in the JVM checking for null would deserve an operator.
OMG, yes!

maybeNull?.getContent()?.toString()

This would improve my coding sooo much.

Currently I use Optional.fromNullable(maybeNull).orElse(new DummyObjectThatReturnsNullOnAllMethodCalls).getContent(), and then repeat the process.

I use "?" constantly in coffee-script. And while I missed ++ for a while in Python, I don't use it in coffee even though it's available.
Would rather they started down the road of getting rid of null.
I was talking about the JVM. ;)
Coincidentally, I've had a little discussion with a non-programmer friend of mine about this operator the other day. He does a little scripting in a game maker program sometimes, and told me that the ++ operator confused him way more than it ever helped him, because he keeps typing stuff like "x + 7" instead of "x = x + 7"
Almost every C and C++ book I've seen has an, imho, needless chapter on why "y = x++" and "y = ++x" are not the same thing. This does not reduce clutter.
Public service announcement: If you can't keep this stuff straight, C++ may not be for you.

Edit: I'm only half-joking. Removing postincrement and postdecrement from C++, as some people are suggesting, would be like removing the oil filler cap from a chain saw. The tool would still be dangerous to use, but now it's annoying to use as well.

I'm just perturbed by how many people are describing x++ as equivalent to x+=1
That's the fault of the authors, not the fault of the language feature. And IMO I've not really found the difference confusing in practice.
We don't have `++` and `--` in Rust either, and I really don't mind. The amount of times I've went to do a `++` where a `+= 1` was clutter has been perhaps one or two times.

Then again, my most common use for `++` was `for (;;) {}` index, and we have better in these new languages like Rust and Swift.

There are millions of people in this world trying to learn to code and understand the layers upon layers of cruft and quirks we've added. I don't mind the `++` or `--` operators, but I certainly don't mind them being gone either. They add extra complexity to code which is already arguably too complex.

In any case, I favor understandability over guesswork, and `++` is another odd cornercase which you have to mentally `grep` over.

Oh, I've just closed a Haskell window, saw the title and thought "how would I concatenate strings?", but I'm digressing...

But no, not only for for(;;). There's also the too common array traversal:

while(something) a[x] = b[x++];

And lots and lots of ugly but useful uses in pointer arithmetics where they make things clear. They have no place in any other language, but I'd really miss both operators in C.

> while(something) a[x] = b[x++];

Wait, isn't this an undefined behavior? Is the order of evaluations of `x` in the left side and `x++` in the right side defined? I'm always confused at things like this!

I dunno. I always thought the ++ operator was evaluated after the entire statement, and every compiler that I could get my hands on behaved that way.

But, well, the specs are another matter entirely.

Hah, just this sort of confusion is part of the proposal to drop ++ and -- from Swift.

x++ returns x and then increments it, so yes the spec agrees with your intuition here.

Whereas ++x increments x and then returns the incremented x.

That subtle difference between x++ and ++x has been the debugging nightmare of many a C developer over the years. It's also why there's a fun irony in the C++ name and why people say the actual successor to C will be ++C.

What?

I was talking about my statement at the upper comment. I used x++ there, not ++x. The doubt is about the value of the other x.

The difference you talk is about the main behavior of the operators. You won't find any description of them that does not state it.

Well, I made the wrong assumption in what was being asked then, I guess. I would presume the "left to right" rule is more generally assumed knowledge in C/C++ than postfix/prefix distinction of ++/-- which are pretty much the only unary operators with such a distinction in the language, whereas "left to right" is a rather underlying general rule and one in which you generally assume people are familiar with.

My apologies for answering the wrong question, but yes in that case the standard is also mostly clear that you can assume that things are evaluated from left to right in C/C++ and thus the first x in the line should be evaluated prior to the x++ later in the line...

Just to update, yes, it's undefined behavior.

Every compiler seems to act the same way today, but some specs oriented optimizer might play havoc with that line.

"These operators increase the burden to learn Swift as a first programming language"

Come on. There are legitimate reasons not to carry one language's expressions to another, but this isn't a good one. Most people first learn of ++/-- as "By the way, you can use ++ as a shortcut to add one" and leave it at that.

But its more complex than that- there are the prefix and postfix forms, which both leave the base incremented but return a different value (before or after the increment). That's the complexity that trips up novices.
Removing ++ et al: ok, they have their problems.

But retaining x += 1? That one has always annoyed me. Why does '+' (and friends) get this special form, but not my functions? Just because they're built-in.

They are useful; no argument there. Largely because 'x' can be a complex reference, and you don't have to type it twice (and the compiler doesn't have to figure out that its the same expression twice). E.g. x=x+1 is short but (rec)FnRec(iRec) = (rec)FnRec(iRec) + 1; is not short. And the compiler gets some great hints when the '+=' form is used (don't calculate the reference twice).

I just want that for my stuff too! E.g. I may have a transformation method Xform(Foo&, Bar) that returns another Foo&. I want to say foo = Xform(foo, bar); but with 'foo' replaced by a complex reference. I have to say FnFooRef(iFoo, "primary", red) = Xform(FnFooRef(iFoo, "primary", red), bar)

instead of FnFooRef(iFoo, "primary", red) Xform= bar;

I want my own 'operators' with the 'op=' syntax supported.

Probably its not terribly useful any more; languages support immutable data and tuples and so much that don't work this way at all.

>Why does '+' (and friends) get this special form, but not my functions?

Your functions can get that (and other) special form. You need to use a language where you can define your own operators. Have you looked at C++, C#, Haskell, or LISP?

Huh. C++? You can overload operators, but define your own? I must have missed something.
Well, I suppose you can #define your own?
#define function(arg1, arg2, arg3) exists for creating macro functions, but nothing exists for naturally creating macro unary or binary operators in C and its descendants.
Each language will have a different meaning of what exactly it means to "define your own". C++ restricts which symbols may be operators, but, you can "define your own +".
In practice it's very useful to distinguish between a language which "just" has operator overloading vs a language that allows custom user-defined symbolic operators. The existence of the latter is actually one of the few complaints that I have about Swift so far, but I'm sure many people will ardently disagree with me here. :P
It's a wonderful feature for writing DSLs, but it's also confusing when you intermingle DSLs with the standard language. It really tends to balloon the amount of information you need to know to read others' code.
> Your functions can get that (and other) special form. You need to use a language where you can define your own operators. Have you looked at C++, C#, Haskell, or LISP?

AFAIK, Lisp doesn't have syntactically-distinct operators at all just functions which may have names similar to operators used in other languages, and C# and C++ don't seem to support custom operators at all. [0]

OTOH, Perl 6 has robust support for custom operators.

[0] except that C++ has apparently been hacked to create custom operators with some limitations via macros [1]

[1] http://www.codeproject.com/Articles/31783/Custom-User-Define...

What "operator" means will be language dependent. An operator is fundamentally just a function, so LISP fits.
Another way to express this is, I'd like a language keyword for "left hand side of assignment". Then for x=x+1 I could say

     x = <LHS> + 1;
It could then get arbitrarily complex. E.g.

     x =  (<LHS> + 1) / atan(<LHS>) - <LHS>;
and no matter how complex 'x' was in practice, the compiler (and the code reader) could keep track of what was happening.
Is there a significant benefit to this over using a new name for the result?

    y = (x + 1) / atan(x) - x;
    x = y; // If you're in a loop and updating some value
If would hope/imagine that a compiler could reduce the two to the same code - and I don't think it reads any worse. Is there a downside beyond the extra line of code?
To be clear: the assignment isn't the optimization; its the use of a symbol for 'x' on the rhs so that the compiler can recognize it. To illustrate that

    X &x = { complex reference expression for x }
    y = (x + 1) / atan(x) - x;
Now the compiler has the clues it needs to write good code. And with language support I don't have to introduce new names for each occurrence; just one name like <LHS> that readers can quickly learn.
> And with language support I don't have to introduce new names for each occurrence;

Having <LHS> as a name is only useful I think if you don't want to give it another name? I was asking what's the downside of giving it a name.

Name proliferation is a famous issue. One-use names are evil.
why ? Could you elaborate ?

Because from my point of view, it could be only the case only if the scopes are weak or underused, or names are bad (too short, ect). After SSA is all about one-use names.

I disagree. Names are comments. You don't want more mutable state across large scopes, but using intermediate names can help comprehension.
I think I get what you mean, but I cannot imagine a single example where your proposed <LHS> keyword would be a good solution: IMHO, if I need a keyword to make the RHS understandable to the reader and the (much smarter) compiler, a macro or function is called for to encapsulate the RHS in a named and documented unit of code.
Other way around; z = x + y is a shorthand syntax for

  z <- copy(x)
  z += y
But you're otherwise right, it's annoying that this shorthand syntax isn't more generally available for user functions.
I may be missing your point, but there's no special casing or special forms going on in Swift.

In Swift, + and += are just operators. They're two separate operators which happen to do similar things. In Swift, an operator can be defined to mutate its left-hand operand, which += is defined to do. You can create your own operators that do that as well.

If you want to do it for methods, Swift has mutating methods which can change the thing they're sent to. In this case, you'd mark your Xform func as "mutating" and then you can write someComplexThing.Xform(bar) and it will mutate someComplexThing in place.

Of course, if you want to support both forms, you end up with a bit of redundancy as you have to define stuff twice. But the built-in stuff is the same way, and you can at least define one in terms of the other to cut down on duplication.

Perl6 lets you define your own operators [0]. I haven't seen them used enough to know how it affects code readability, though.

[0] http://doc.perl6.org/language/functions#Defining_Operators

Code readability will increase, having an operator with tightly defined input(s) type(s) will in fact greatly increase readability and reusability.
Or akin to PHP's pass-by-reference ampersand, you could have something like `&x + 1` which would expand to `x = x + 1`. Dunno what the impact on code readability/maintainability would be, but it does sound nice.

Especially when doing straightforward data manipulations in R or Python, endless lines of `bla = map(bla, fn)` start to look crufty, so much so that Pandas in Python now allows you to add `inplace=True` to almost any data manipulation method to cut down on the verbosity. But then, sprinkling that keyword argument across every line isn't exactly better. Neither is endless chaining. Looks like we could still use some syntactic improvement.

Do you mean something like "compound assignment operators"? Apparently you can define custom operators like:

    func += (inout left: Vector2D, right: Vector2D) {
        left = left + right
    }
https://developer.apple.com/library/ios/documentation/Swift/...
Question of clarification: is this the same concept as Python's __iadd__? I was not aware that this was a "thing" in programming language design.

http://stackoverflow.com/questions/1047021/overriding-in-pyt...

Looking at eliteraspberrie's example, not really. Python's __iadd__ and such are not able to reassign. There is no "inout" in Python. The assignment aspect of __iadd__ is done through self mutation (and an extra hard-coded assignment to support immutable variables).
The assignment aspect of __iadd__ is done like any other assignment in python. The one to one equivalent of eliteraspberrie's would be:

  class Vector2D:
      def __iadd__(self, other)
          return self + other
No "self mutation" as you suggest. a += b is equivalent to a = a.__iadd__(b)
> No "self mutation" as you suggest.

Your example would be the implementation for immutable Vector2Ds, and is implemented for you if you just wrote __add__. (I presume object.__iadd__ falls back to self.__add__.)

The only time you should actually override __iadd__ is for mutable objects, in which case it should look more like

  class Vector2D:
      def __iadd__(self, other)
          for i, x in enumerate(other):
              self[i] += x
          return self
That's the self mutation I was talking about.

Well, strictly that's not OK either, since operators shouldn't be duck-typed. Instead you should do

  class Vector2D:
      def __iadd__(self, other)
          if not isinstance(other, Vector2D):
              return NotImplemented

          for i, x in enumerate(other):
              self[i] += x
          return self
> The only time you should actually override __iadd__ is for mutable objects

What would the rationale be for such a rule?

the docs don't mention anything like that https://docs.python.org/2/library/operator.html and I've never heard it before. In Python, neither integers nor strings are mutable and both support the "x += y" syntax.

The __iadd__ method works the same for both mutable and immutable objects AFAIK

> What would the rationale be for such a rule?

Because __iadd__ automatically delegates to __add__. For immutable objects that's the best you can do, so there's no reason to write both.

Sounds fine to me, what changes to a standard tokenizer and parser would you make to carry out your plan?

I'm not saying this is a shining example of brilliant programming, but it is in a semi-working state and something "in a similar style" (that is, a three-pass tokenizer -> LR parser -> LR parser where scope information and other metadata is computed in the second pass and fed into the third) should be able to handle the changes you're talking about.

https://github.com/dbpokorny/autoclave/

In Swift, += is a separate operator from +, and is defined within the confines of the language. It's not privileged in any particular way:

    func +=(inout lhs: Int, rhs: Int)
and you can just implement this.

You might object that special forms are still privileged, e.g. foo[idx]+=1. But in fact these are not special: one of the surprising features of Swift is that inouts work on computed properties. For example, say we add a mutable property highHalf on UInt64:

    extension UInt64 {
        var highHalf : UInt32 {
            get { return UInt32(self >> 32) }
            set { self = (self & 0xFFFFFFFF) | (UInt64(newValue) << 32) }
        }
    }
Now you can do this:

    var x = UInt64.max
    x.highHalf -= 1
So complex references can be used for any inout. That's how array indexing works.

Swift is the first language I've encountered that works this way; are there others?

> Swift is the first language I've encountered that works this way; are there others?

Lisp, of course :-) Common Lisp's SETF and related macros work this way. E.g.,

  (incf (ldb (byte 3 5) x))
would increment the "byte" (CL's term for an arbitrary bit field) of width 3 at offset 5 of X.

INCF is defined in terms of SETF. Of course, the set of macros that can update a place is user-extensible. So if you wanted one that multiplies the value in the place by two, you could just write something like this (the trailing "f" in the name, as you might guess, is the convention for such a macro):

  (define-modify-macro doublef () (lambda (x) (* x 2)))
then you could call it like this:

  (doublef (ldb (byte 3 5) x))
to double the value in the bit field.

(EDIT: used lambda expression instead of helper function.)

Isn't this how C++ works as well? operator+= is definable for any user defined types and typically you'll add an overloaded operator[] which returns a reference so that things like operator+= works as you'd expect within the context of a collection.

I have some old code somewhere for images which I'm sure does something to the effect of:

    image[x, y] *= scale;
where Image::operator[] returns a Pixel&.
Not quite. C++'s references are syntactic sugar on top of pointers: a Foo& always needs a Foo to point to. But Swift's inouts are implemented as a pair of closures: a getter and a setter, which need not just modify a Foo.

Consider the much-hated vector<bool>, implemented as a packed bit array. Since you can't return a reference to a bit, operator[] must create a special wrapper class that holds a reference to the word and the bit offset, and then overload operator= and perform other tricks. It's famously leaky and gross.

In Swift, we can implement this optimization much more cleanly. inout lifetimes are always scoped, and when the scope ends, the new value is written back to the object via its setter. Our `inout boolean` is not backed by a boolean at all: it's backed by a getter and setter which can do arbitrary things, like mask and shift a word.

>But retaining x += 1? That one has always annoyed me. Why does '+' (and friends) get this special form, but not my functions?

The reason is that I don't want to see you escape your strings by writing

  input escapequotes= input
That's why. come on. who wants to read that?
But it would be

   input +'= input
and the reverse

   input -'= input
or, alternatively,

   input \'= input
and

   input !'= input
If you code does this often enough, that may even be useful (but also, your code would be bad)
Get rid of `x += 1` also. Its just shorthand for `x = x + 1`. /sarcasm
Why remove x++ and not x += 1?

Demand X = X + 1. For clarity/readability/formatting.

> Why remove x++ and not x += 1?

A key part of the reason for removing the ++/-- set of operators seems to be that they conflict with Swift's pattern of mutating operators returning void. (An alternative offered was revising them so that they followed that pattern.)

+=/-=, like simple assignment, do not have that problem.

Well, I assume that it's because

  myObject.someVariable = myObject.someVariable + 1
is harder to read than

  myObject.someVariable += 1
Also it's annoying to type and increases the chance of typos.
I tend to agree with removal. Nobody writes

    for (i=0;i<n;i++) *a++ = *b++;
any more.
All the cool kids use Null-terminated strings now.

    while (*a++ = *b++);
I have rarely used ++ and -- outside of inc/decrementing pointers and loop counters in C code. They probably won't be missed in Swift.
While I agree that having both pre- and post- versions is confusing overkill, ++ is no more sugar for x += 1 than x+x is sugar for x*2.

Increment is the fundamental operation, += is sugar for repeated incrementation, not the other way around.

Good, I always sticked to += 1 because it felt better. Weird to see I'm not alone.

I could never really memorise the difference between i++ and ++i because it just seemed like such an obscure thing to have. It's really really weird (and cool) to see someone suggesting removing it.

"When the return value is needed, the Swift += operator cannot be used in-line, since (unlike C) it returns Void."

Why was this decision made?

So you can't do this:

a += b -= c;

Don't ask me in which order it executes, I would need to read the C standard again and wrap my head around how this case is described therein.

I'm also not sure wether this is defined or undefined behaviour:

a += b -= c *= a;

Now throw a few ++ and -- in there, and boy howdy.
"So you can't do this: a += b -= c; Don't ask me in which order it executes,"

thx for the reply @legulere, I can now see the void, why would the language allow syntax that smells so bad? Can you do this in "c"?

scala has no ++ or -- operators. It's a-okay. Swift is shaping up to look a lot like scala actually. The biggest problem with ++ and -- operators is that they hide a side-effect in another unrelated operation. In a language that supports more functional approaches at the outset, it makes sense to just omit these operators I think.
> Keep both x++ and ++x in the language, even though they do the same thing.

?

> > Keep both x++ and ++x in the language, even though they do the same thing.

> ?

That was a subalternative underneath the alternative of changing the operators to return Void like other assignment operators. ++x and x++ differ in that the former returns the value after the increment, the latter the value before; if they return void, all they do is the increment with no difference.

This a delayed response for which I apologise, but thank you for yours, this makes complete sense now. I must have missed this at the time. Makes sense now.
(comment deleted)