Swift Decrements C-Style Syntax
Why is this Languages meme funny?
Level 1: Tiny Button Removed
Imagine a toy has a tiny shortcut button that spins a wheel once, but sometimes it spins before counting and sometimes it counts before spinning. People who know the toy love the shortcut, but new people keep getting confused. Swift decided to remove the tricky button and make everyone use the clearer handle instead. The joke is that programmers can get very dramatic about losing one tiny button.
Level 2: Increment Drama
The ++ operator usually means "add one." In languages that support it, i++ increments i after producing its old value, while ++i increments first and then produces the new value. The same pattern applies to --, which subtracts one.
That difference can matter:
// Old Swift style before removal
let oldValue = i++
// Clearer replacement
i += 1
The problem is not that adding one is hard. The problem is that ++ combines two actions: it changes a variable and can also produce a value. When code uses that value inside a larger expression, readers have to track both the mutation and the timing. That is easy in a tiny loop and unpleasant in clever code.
Swift Evolution is the process where changes to the Swift language are proposed, discussed, accepted or rejected, and eventually implemented. The screenshot shows proposal SE-0004, authored by Chris Lattner, with status Implemented (Swift 3). In plain terms: Swift's maintainers decided that this syntax caused more confusion than benefit, and the language changed.
For junior developers, this is a good example of a breaking change made for language cleanliness. A feature can be popular in older languages and still be removed from a newer one if it does not match the newer language's goals. Swift was not trying to be "C with nicer app APIs." It was trying to be a safer, clearer language for modern Apple-platform development, even if that meant telling old habits to update their resumes.
Level 3: Syntax Loses Weight
The screenshot shows a Swift Evolution proposal titled:
Remove the
++and--operators
The red underline under Status: Implemented (Swift 3) is the punchline's little legal stamp: this was not just a cranky blog post. Swift actually removed the familiar C-style increment and decrement operators. The second underline points to the word confusing in the introduction, which explains the meme's attitude: Swift looked at one of the most recognizable programming-language conveniences and decided it was not worth keeping.
That is funny because ++ and -- are almost sacred fossils in C-family languages. C, C++, Java, JavaScript, Objective-C, and C# all made generations of developers comfortable with i++ in loops. The operators are tiny, expressive, and visually iconic. They are also a compact source of subtlety: prefix versus postfix forms return different values, mutation is hidden inside an expression, and clever code can smuggle side effects into places where readers would prefer not to discover them.
The post caption says:
No one: Literally no one: swift developers:
That framing works because language committees and evolution processes often look absurd from the outside. Nobody in ordinary application work wakes up demanding fewer ways to add one to a variable. But language designers do think about the long-term cost of every feature: what beginners must learn, what style guides must forbid, what compilers must diagnose, what migrations must support, and what kind of code the feature encourages.
Swift's design taste has always leaned toward clarity at the call site, explicitness around mutation, and discouraging C tricks that make code dense but harder to read. Removing ++ and -- fits that personality. Swift already had x += 1, for-in loops, ranges, and collection APIs that reduced the need for manual index juggling. In that world, the operators became less like essential tools and more like heritage furniture: familiar, maybe charming, but awkward in the new house.
The experienced-developer laugh comes from the collision between ergonomics and ideology. A small operator can trigger a giant argument because syntax is muscle memory. Remove one character pair and suddenly every forum thread becomes a civilizational referendum on readability, beginner friendliness, C compatibility, and whether i += 1 is tyranny. Programming languages are tools, but developers defend their favorite punctuation like family heirlooms.
Description
The image is a GitHub page screenshot from "swift-evolution / proposals / 0004-remove-pre-post-inc-decrement.md" on the master branch. The document title reads "Remove the ++ and -- operators," with bullets showing "Proposal: SE-0004," "Author: Chris Lattner," "Status: Implemented (Swift 3)," and "Commit: apple/swift@8e12008," with the status line underlined in red. The visible introduction says the increment/decrement operators were added early in Swift as a carry-over from C, without much consideration, and recommends removing them because they are "confusing" and not carrying their weight, with "confusing" underlined. The joke is that Swift deliberately removed a familiar C-family convenience operator in the name of language clarity.
Comments
148Comment deleted
Swift removed `++` because apparently readability was the one counter nobody wanted to increment implicitly.
I am still waiting for implementation of that operators in Python :( Comment deleted
LOL PYTHON DOESNT HAVE IT? Comment deleted
nope Comment deleted
Only +=1 and -=1 :) Comment deleted
Lua devs: what are these typos? Comment deleted
No. Don't blame Python, it's just a bash for running libraries.... oh wait, EVEN BASH CAN ++. Comment deleted
Don't tell me that you're unironically calling bash a good programming or scripting language. If you've ever written anything even remotely complex with it, you'd never mention it as a positive example. It's a good tool for one simple thing, CLI and simple scripts and ++ operator doesn't improve it in any way Comment deleted
I wrote a disassembler in Bash once 💀 Comment deleted
Python has += and -= ++ or -- are redundant then Comment deleted
everything is redundant, that's not a valid argument Comment deleted
Not at all. How did you even come to this? Comment deleted
a += 1 is not identical to a++ if you're using a++ as an expression rather than a statement therefore, i interpreted your message as saying "you can always avoid a++" i replied that you can avoid everything that way Comment deleted
a+=1 is not an expression in python Comment deleted
I know Comment deleted
If you continue thinking that syntactic sugar is redundant then you might as well end with assembly. Comment deleted
Those things are interchangeable. They both are syntactic sugar Comment deleted
What about ++i? Comment deleted
Lua does not have += nor -= because they are redundant. Besides, `variableName = variableName + 1 conveys intent much better, does it not? Also, Lua lacks continue because it can be implemented with do repeat ... break until true end 🐳. Comment deleted
Lua has a global table that contains all variables, accessible from everywhere. It's more of a scripting language for writing add-ons. Comment deleted
I meant that you should have either += or ++ in a language. If you have one, the second is redundant. Python already have the first option. Break and continue are different instructions, aren't they? I'm not familiar with Lua at all Comment deleted
The "while" loop is also redundant because it's essentially a special case of the "for" loop. And "switch" is just another "if". Comment deleted
In many languages 'while' is not just a case of 'for'. And switch is another if that's why python doesn't have it. (' match case' isn't the same) Comment deleted
Both 'for' and 'while' are just syntax sugar for 'if' combined with 'goto'. Comment deleted
And what 'goto' is a syntactic sugar of? Comment deleted
ask the pdp11 Comment deleted
jmp ig Comment deleted
In C 'goto' is syntactic sugar for an assembler JMP instruction, which can be short, long, or absolute. In interpreted languages it results in a change to the instruction pointer- so it's += / -=. 😊 Comment deleted
well why u need += when u have =. += is redundant then Comment deleted
No, they have different purpose Comment deleted
you can replace += with =, just like you can replace ++ with += Comment deleted
You can replace everything, but this has no sense Comment deleted
that is what you said. you said, that if we have += then ++ is redundant Comment deleted
It's two identical syntactic sugas. var = var + 1 is not a sugar Comment deleted
int a = 5; int b = a++; printf(a); // 6 printf(b); //5 Comment deleted
And? Comment deleted
you can't do it with += Comment deleted
Ok, don't see much difference with a+1. But you will say that everything can be replaced then 👍 Comment deleted
Well, you said that += replaces ++, not me. I'm trying to prove that these are different operators providing different conveniences. I just don’t understand how, in your understanding, replacing ++ with += is different from replacing += with = Comment deleted
Chris Lattner code leaked Comment deleted
pure headache Comment deleted
but ++ and — are far better it has style inc++ it just sucks ass inc+=1 Comment deleted
and here comes ++inc and inc++ and that is confusing Comment deleted
as if async/await is not confusing Comment deleted
How it can be confusing if you know a bit of asynchronous systems Comment deleted
running a task in background was pretty hard back then writing your own executor is difficult too translating a synchronous operation into an async one is not an easy process either you also have to consider data races, etc., which you didn't need in the synchronous case Comment deleted
Yes, you can learn stuff, and then async/await becomes simple to use, but so you can do with ++/-- Comment deleted
waaaat? Comment deleted
you don't have to use ++inc but yes, sometimes it can be hard to understand (if used incorrectly) Comment deleted
This is the reason why Rust® tells to just use += 1 Comment deleted
A question of style. I like both. But the second is more reusable as one can add different numbers, not just 1 Comment deleted
inc++++++++ Comment deleted
Very easy to understand 👍 (not at all) Comment deleted
jesus Comment deleted
imho, ++ only brings more confusion. I remember learning C in college and being pissed from every other student writing loops differently. the operator itself is neat but it just adds too much variations for such a simple thing a =+ 1 is almost universally accepted by now a = a + 1 for the win Comment deleted
sounds like a you problem Comment deleted
Welp if ++ operators aren't confusing, then it should be trivial to tell how something like ++i + i++ would be executed and what would it return Comment deleted
Sure, ++i increases i and returns the new state (i.e. after increase), i++ increases i and returns the previous state (i.e. before increase). Comment deleted
what's the result if i = 10 Comment deleted
11 for both i and value. Comment deleted
You've misread, let me write it in pseudo-c int i = 10; print(++i + i++); Comment deleted
this reminds me of my super-dooper javelin operator Comment deleted
print(11 + 11), it will print 22, i will be 12 after the operations. Comment deleted
except some of the C++ compilers return 23 Comment deleted
Sure, but you will receive warnings about unsequenced modifications. However, it's like using functions that modify a global value within one expression - it's possible, but not a typical use case. Comment deleted
You may receive warnings, but you may also not receive them. You may encounter inconsistent behavior for such expressions across different compilers. Or you may not. You've mentioned that the operator isn't confusing, and yet misinterpreted the result of one-liner. I think my point about it being not a trivial operator to understand given more complex cases stands Comment deleted
You'll encounter inconsistent behavior like this everywhere, e.g. some_func(a.update(1), a.update(2)) Comment deleted
oh my do I have a solution for this lol, but I'd blow my cover Comment deleted
As I mentioned, it's the same for subsequent function calls that modify the same value within a single expression. You should avoid modifying the value more than once, regardless of how you do it. Comment deleted
I definitely agree with this, but even if you need to post/preincrement something, I think it's just better to do this explicitly, even if it costs you one extra line of code. Just to make the intent 100% clear for other devs that may want to read your code. I can also agree with you that if you use these operators for simple cases they are trivial to understand, but they really do tend to be misused a lot Comment deleted
Nearly every language feature can (and will) be misused. No amount of language design and static analysis can prevent people from writing garbage if they feel like it. Comment deleted
Totally, but that's not an excuse to design stuff that doesn't bring extensive benefits given the drawbacks, in my opinion. These operators usually don't offer much more than just being shorter forms of explicit assignment Thing is, if you just judge by that logic, there's also no point in having good names for your variables or introducing enums in your program. You can totally misuse some flag from enum, but it's still better to use a named enum variant rather than a magic int Comment deleted
You're right, it can be clearer to use an extra line for simplicity. However, I find nothing complex about ++. It’s like being advised to avoid -= in favor of += with a negative number, to remove a "complex" operation because subtraction is supposedly more complex and seeing i-=-10 might make you mad. Comment deleted
if I designed this, I'd emit a warning during the parsing stage Comment deleted
You never need a ++ in Python. Use iterators, that is more pythonic. Comment deleted
pythonic style works until you have to do complicated shit. I do use +=1 sometimes, because you can't just use iterators everywhere. Comment deleted
Show me a really good example. I do c# now and I barely use ++ even there. And every time I do, the code smells. Comment deleted
sure, let me show you a simple example of complex code outside any project you'd need context for /s Comment deleted
The ++ operator is best used when you need to increment something by one, and only by one, as part of the intended design. For example, seeing iterator++ makes it clear that the iterator will be incremented by 1 each time. Using += 1 instead of ++ is poor style because it draws unnecessary attention to the increment, implying that a different increment value may be possible here. It's like using public instead of a more restrictive access modifier - it suggests something atypical is happening. I would avoid += 1 except in rare cases where you specifically need to communicate that other increment values are supported. Overall, ++ leads to cleaner and more readable code in most situations. Comment deleted
iterating using offsets in python is not how it was designed. And offsetting smth by one is used for iteration in 99.99% of cases. Use enumerate, zip etc. Python gives you a great choice to not use ++ or +=1. Comment deleted
you just can't not use offsets in any slightly complicated algorithm Comment deleted
show me any slightly complicated algorithm and I will try to not use offsets (specifically an offset by one) Moreover, you probably do not want to write a really complicated stuff in pure python. You will end up using numpy or other suitable lib. Comment deleted
Well here's the simplest one # arr = [1, 2, 3, 4, 5, 6] prefix_sums = [0] * (len(arr) + 1) for i in range(len(arr)): prefix_sums[i + 1] = prefix_sums[i] + arr[i] Comment deleted
use list comprehension + zip, if I get right what you try to achieve Comment deleted
could you elaborate please? i don't see how list comprehension would help here Comment deleted
And I'd use a cumsum from numpy here, if you want speed. Comment deleted
cumsum won't work if you need something slightly different, e.g. string = "Hello, world!" prefix_rolling_hash = [0] for i, c in enumerate(string): prefix_rolling_hash[i + 1] = (prefix_rolling_hash[i] * BASE + ord(c)) % MOD Comment deleted
https://chat.openai.com/share/253830bc-657a-4989-a77d-724af7de0df7 I was just curious, how would chatgpt behave. Comment deleted
now ask if to avoid reallocations... Comment deleted
If you care about this stuff, you should use performant libraries. But yes, everything comes with its price. Comment deleted
what if there aren't performant libraries to do what i want? and i don't wanna switch to another languages because i'm happy with the other abstrations python provides via libraries? Comment deleted
say, i don't wanna parse a complicated text format (e.g. xml), or send/listen to HTTP requests, or write a data visualizer in C, because Python provides easier-to-use alternatives, but there's one part I'd rather write efficiently Comment deleted
this is, like, the exact use case I've stumbled upon recently — I've got a complicated service that, among parsing data/sorting data/presenting data/listening to user requests/formatting HTML needs to do some matrix calc in the middle of this process Comment deleted
For me python is like glue, and it is perfect in that. It glues together all the libraries written in other languages. You can write the small part you need to be performant in C and call it from python. But trust me, allocations will rarely be a sole issue for performant code in python. And yes, numpy will help to make all the example you gave really fast. Comment deleted
well (not arguing, just adding)—Python has become my default language for anything slightly complicated, and often performant stuff is complicated so I'm sort of stuck between two worlds Comment deleted
You can try JIT or numpy for complex math/vector operations (and in my cases vectorization is the way in most cases). Comment deleted
https://chat.openai.com/share/2a7d21a0-8bcd-40f0-841d-ad40f2dc17a8 And for this one even better Comment deleted
have a field trip Comment deleted
That is not even formatted, looks like someone took a c code and put it into python without much of a thought. Sure thing it is not idiomatic Comment deleted
I wrote it by hand, using pseudocode from wikipedia at times, but in most cases just by myself. You try implementing mergesort in a pythonic way Comment deleted
yeah honestly idk how to implement merge sort in a pythonic way Comment deleted
and it is formatted, just not the way you'd like it to be Comment deleted
Ok, this might fall into that 0.01% of cases, but usually in real python applications you do not code such stuff. Comment deleted
is this not a real python application? Comment deleted
He's referring to a usage pattern like this: from some.lib.written.in.c import DoTheMagic DoTheMagic() As you can see there is no need in ++ or +=1 Comment deleted
Seems it is purely academic or for fun. You see, each tool is good for it's purpose and python is not a proper tool to write low level high performing code. You could also try writing merge sort in bash let's say. If you did thst by hand, you have my respect, though Comment deleted
it's for visualization of sorting algorithms. The implementation of the algs themselves doesn't need to be fast, just demonstrate the pros and cons of each alg and each variant of it Comment deleted
i.e. while the algorithms have to be fast, the execution of those fast algorithms doesn't Comment deleted
but yes, usually, iterators are enough Comment deleted
Sure, enumerate is useful. But saying "great choice not to use" seems quite Orwellian, because it's literally the opposite of having a choice. Comment deleted
There should be one-- and preferably only one --obvious way to do it. Comment deleted
there's like 5 ways to format strings in python 🙄 Comment deleted
const a = 1; const b = a++; has bad readability const a = 1; const b = a; a += 1; is easier to read. You don't need to stop and think about this clever trick with ++ Comment deleted
yes, which is why no one writes the former Comment deleted
Both ways aren't good because they are constants. Comment deleted
lol sorry my bad. it should be let for sure Comment deleted
Is it harder to read? let a = 1; let b = a; a++; Usage examples of ++ from current project: if (processingCounter++ >= 10) { throw new InvalidOperationException($"Possible loop for sequence {data.SequenceId}"); } ... if (--_disposesCounter <= 0) { _instance?.Dispose(); _instance = null; } ... var user = context.Users[context.UserNotificationIndex++]; ... Temperature = GetNumber(telemetryData, readIndex++), Humidity = GetNumber(telemetryData, readIndex++), CarbonDioxide = GetNumber(telemetryData, readIndex++), It simplifies things when used correctly. As an experienced enterprise developer, I could make every implementation of ++ not merely as +=1 but as a dedicated class factory solely for this operation. It would conform to best practices and coding conventions, accessible via dependency injection, mockable, well-documented, and covered with unit-tests. I might even package it as a NuGet to give DevOps the pleasure of integrating it into CI/CD pipelines. Five working days, ten meetings and it would be operational. But I'm too lazy for these games, so I'll continue to use ++ and ponder the imminent degradation of the developer community. Comment deleted
++ reads well when it is not in expressions. But when ++ is in an expression, it becomes more of an attentiveness task. This is a puzzle for the reader. This dramatically breaks readability Comment deleted
This can be true for any function that modifies its result. I once encountered a real mess: if (obj.a(obj2.b()) && (obj.c() || obj.d())), where all of a, b, c, and d methods altered obj. It felt like an escape room filled with something brown... Comment deleted
instance?.Dispose what is that question mark here? is that a special language? Comment deleted
its pretty fresh js feature Comment deleted
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining Comment deleted
In C# it's null-conditional operator, in TS/JS it's optional-chaining. Basically: a?.b is equal to ternary (a == null ? null : a.b) Comment deleted
processingCounter++ >= 10 This could be an interview question for knowledge of the nuances of a programming language. But in a real project it's just shitty code Comment deleted
let a = 1; let b = a; a++; and in this case ++ is ok Comment deleted
i want to believe ++inc Comment deleted
nice !! just another reason to avoid learning Swift Comment deleted
for (int i = 0; i < size; i++) vs for (int i = 0; i < size; i += 1) it hurts my eyes Comment deleted
There is no C-style loop in swift 🙂 Comment deleted
for i in 0..<size Comment deleted
Meanwhile android devs using kotlin: Comment deleted
a very naive code that produces the same result: rolling_sum = 0 prefix_sums = [0] for item in arr: rolling_sum += item prefix_sums.append(rolling_sum) print(prefix_sums) Comment deleted
And I believe it is more readable also, as you get the idea behind the code Comment deleted
append would cause reallocations though Comment deleted
The question is about the operator being confusing. And no matter how you look at it, it is confusing. It depends on a lot of hidden magic that happens under the hood. It's a headache to implement a proper parser and emit a proper warning for stuff like this, and if you try hard enough, it's not hard to come up with much more cases like this, where the result would be extremely unobvious. Why introduce a flawed way to do something and even write a static analysis tool in your compiler/interpreter if in most cases just using i += 1 is sufficient? Comment deleted
It's only sufficient in most cases, just like Python's performance is sufficient in most cases, or C is safe in most cases, etc. Comment deleted
I've been using a language without that operator for years now and I'm yet to encounter a single use case where I missed it, coming from C++ Comment deleted
idk I miss *dst++ = *src++ Comment deleted
I believe neither Swift nor Python has any need for pointer arithmetic though? Please correct me if I'm wrong. Also if the idea is to just copy some memory from src to dst, won't memcpy be a more performant and safe way to do this? Comment deleted
It has never been confusing to me. I just treat ++/-- as shortcuts for simple functions. Comment deleted
no, that's UB Comment deleted
That is the essence of python Comment deleted
https://github.com/apple/swift-evolution/blob/main/proposals/0004-remove-pre-post-inc-decrement.md couldve at least linked the full reasoning... Comment deleted
popular eslint configs in js are afraid too of using ++ and -- Comment deleted
So many languages don't actually have these operators... No I'm not talking about python... Take rust for example Comment deleted
and you are using var in your project. wtf? Comment deleted
ohh. is it c#? Comment deleted
This syntax is also used in swift Comment deleted