Skip to content
DevMeme
5154 of 7435
Swift Decrements C-Style Syntax
Languages Post #5642, on Nov 8, 2023 in TG

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

148
Anonymous ★ Top Pick Swift removed `++` because apparently readability was the one counter nobody wanted to increment implicitly.
  1. Anonymous ★ Top Pick

    Swift removed `++` because apparently readability was the one counter nobody wanted to increment implicitly.

  2. @v1lezor 2y

    I am still waiting for implementation of that operators in Python :(

    1. @SomeWhereIBelong 2y

      LOL PYTHON DOESNT HAVE IT?

      1. @v1lezor 2y

        nope

      2. @vladyslav_google 2y

        Only +=1 and -=1 :)

        1. @zeminori 2y

          Lua devs: what are these typos?

      3. @Araalith 2y

        No. Don't blame Python, it's just a bash for running libraries.... oh wait, EVEN BASH CAN ++.

        1. @Anfid 2y

          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

          1. @purplesyringa 2y

            I wrote a disassembler in Bash once 💀

    2. @the_sage 2y

      Python has += and -= ++ or -- are redundant then

      1. @purplesyringa 2y

        everything is redundant, that's not a valid argument

        1. @the_sage 2y

          Not at all. How did you even come to this?

          1. @purplesyringa 2y

            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

            1. @somebody48 2y

              a+=1 is not an expression in python

              1. @purplesyringa 2y

                I know

      2. @namingfunctionerror 2y

        If you continue thinking that syntactic sugar is redundant then you might as well end with assembly.

        1. @the_sage 2y

          Those things are interchangeable. They both are syntactic sugar

      3. @Araalith 2y

        What about ++i?

      4. @anilakar 2y

        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 🐳.

        1. @Araalith 2y

          Lua has a global table that contains all variables, accessible from everywhere. It's more of a scripting language for writing add-ons.

        2. @the_sage 2y

          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

          1. @Araalith 2y

            The "while" loop is also redundant because it's essentially a special case of the "for" loop. And "switch" is just another "if".

            1. @the_sage 2y

              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)

              1. @Araalith 2y

                Both 'for' and 'while' are just syntax sugar for 'if' combined with 'goto'.

                1. @the_sage 2y

                  And what 'goto' is a syntactic sugar of?

                  1. @L2CacheGay 2y

                    ask the pdp11

                  2. @purplesyringa 2y

                    jmp ig

                  3. @Araalith 2y

                    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 += / -=. 😊

      5. @Dorikan 2y

        well why u need += when u have =. += is redundant then

        1. @the_sage 2y

          No, they have different purpose

          1. @Dorikan 2y

            you can replace += with =, just like you can replace ++ with +=

            1. @the_sage 2y

              You can replace everything, but this has no sense

              1. @Dorikan 2y

                that is what you said. you said, that if we have += then ++ is redundant

                1. @the_sage 2y

                  It's two identical syntactic sugas. var = var + 1 is not a sugar

                  1. @Dorikan 2y

                    int a = 5; int b = a++; printf(a); // 6 printf(b); //5

                    1. @the_sage 2y

                      And?

                      1. @Dorikan 2y

                        you can't do it with +=

                        1. @the_sage 2y

                          Ok, don't see much difference with a+1. But you will say that everything can be replaced then 👍

                          1. @Dorikan 2y

                            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 =

  3. @Sp1cyP3pp3r 2y

    Chris Lattner code leaked

    1. @MrZarei 2y

      pure headache

  4. @v1lezor 2y

    but ++ and — are far better it has style inc++ it just sucks ass inc+=1

    1. @XmasApple 2y

      and here comes ++inc and inc++ and that is confusing

      1. @purplesyringa 2y

        as if async/await is not confusing

        1. @the_sage 2y

          How it can be confusing if you know a bit of asynchronous systems

          1. @purplesyringa 2y

            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

            1. @purplesyringa 2y

              Yes, you can learn stuff, and then async/await becomes simple to use, but so you can do with ++/--

      2. @erizpl 2y

        waaaat?

      3. @v1lezor 2y

        you don't have to use ++inc but yes, sometimes it can be hard to understand (if used incorrectly)

      4. @zaspirin 2y

        This is the reason why Rust® tells to just use += 1

    2. @the_sage 2y

      A question of style. I like both. But the second is more reusable as one can add different numbers, not just 1

      1. @Sp1cyP3pp3r 2y

        inc++++++++

        1. @the_sage 2y

          Very easy to understand 👍 (not at all)

        2. @purplesyringa 2y

          jesus

    3. @hotsadboi 2y

      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

      1. @Sp1cyP3pp3r 2y

        sounds like a you problem

        1. @Anfid 2y

          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

          1. @Araalith 2y

            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).

            1. @Anfid 2y

              what's the result if i = 10

              1. @Araalith 2y

                11 for both i and value.

                1. @Anfid 2y

                  You've misread, let me write it in pseudo-c int i = 10; print(++i + i++);

                  1. @callofvoid0 2y

                    this reminds me of my super-dooper javelin operator

                  2. @Araalith 2y

                    print(11 + 11), it will print 22, i will be 12 after the operations.

                    1. @Anfid 2y

                      except some of the C++ compilers return 23

                      1. @Araalith 2y

                        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.

                        1. @Anfid 2y

                          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

                          1. @purplesyringa 2y

                            You'll encounter inconsistent behavior like this everywhere, e.g. some_func(a.update(1), a.update(2))

                            1. @Anfid 2y

                              oh my do I have a solution for this lol, but I'd blow my cover

                          2. @Araalith 2y

                            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.

                            1. @Anfid 2y

                              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

                              1. @x4erem6a 2y

                                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.

                                1. @Anfid 2y

                                  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

                              2. @Araalith 2y

                                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.

                  3. @purplesyringa 2y

                    if I designed this, I'd emit a warning during the parsing stage

  5. @adozzer 2y

    You never need a ++ in Python. Use iterators, that is more pythonic.

    1. @RiedleroD 2y

      pythonic style works until you have to do complicated shit. I do use +=1 sometimes, because you can't just use iterators everywhere.

      1. @adozzer 2y

        Show me a really good example. I do c# now and I barely use ++ even there. And every time I do, the code smells.

        1. @RiedleroD 2y

          sure, let me show you a simple example of complex code outside any project you'd need context for /s

        2. @Araalith 2y

          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.

          1. @adozzer 2y

            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.

            1. @purplesyringa 2y

              you just can't not use offsets in any slightly complicated algorithm

              1. @adozzer 2y

                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.

                1. @purplesyringa 2y

                  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]

                  1. @adozzer 2y

                    use list comprehension + zip, if I get right what you try to achieve

                    1. @purplesyringa 2y

                      could you elaborate please? i don't see how list comprehension would help here

                  2. @adozzer 2y

                    And I'd use a cumsum from numpy here, if you want speed.

                    1. @purplesyringa 2y

                      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

                      1. @adozzer 2y

                        https://chat.openai.com/share/253830bc-657a-4989-a77d-724af7de0df7 I was just curious, how would chatgpt behave.

                        1. @purplesyringa 2y

                          now ask if to avoid reallocations...

                          1. @adozzer 2y

                            If you care about this stuff, you should use performant libraries. But yes, everything comes with its price.

                            1. @purplesyringa 2y

                              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?

                              1. @purplesyringa 2y

                                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

                                1. @purplesyringa 2y

                                  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

                                2. @adozzer 2y

                                  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.

                                  1. @purplesyringa 2y

                                    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

                                    1. @adozzer 2y

                                      You can try JIT or numpy for complex math/vector operations (and in my cases vectorization is the way in most cases).

                  3. @adozzer 2y

                    https://chat.openai.com/share/2a7d21a0-8bcd-40f0-841d-ad40f2dc17a8 And for this one even better

                2. @RiedleroD 2y

                  have a field trip

                  1. @adozzer 2y

                    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

                    1. @RiedleroD 2y

                      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

                      1. @purplesyringa 2y

                        yeah honestly idk how to implement merge sort in a pythonic way

                    2. @RiedleroD 2y

                      and it is formatted, just not the way you'd like it to be

                  2. @adozzer 2y

                    Ok, this might fall into that 0.01% of cases, but usually in real python applications you do not code such stuff.

                    1. @RiedleroD 2y

                      is this not a real python application?

                      1. @Araalith 2y

                        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

                      2. @adozzer 2y

                        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

                        1. @RiedleroD 2y

                          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

                          1. @RiedleroD 2y

                            i.e. while the algorithms have to be fast, the execution of those fast algorithms doesn't

                    2. @RiedleroD 2y

                      but yes, usually, iterators are enough

            2. @Araalith 2y

              Sure, enumerate is useful. But saying "great choice not to use" seems quite Orwellian, because it's literally the opposite of having a choice.

              1. @adozzer 2y

                There should be one-- and preferably only one --obvious way to do it.

                1. @RiedleroD 2y

                  there's like 5 ways to format strings in python 🙄

          2. dev_meme 2y

            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 ++

            1. @purplesyringa 2y

              yes, which is why no one writes the former

            2. @Araalith 2y

              Both ways aren't good because they are constants.

              1. dev_meme 2y

                lol sorry my bad. it should be let for sure

                1. @Araalith 2y

                  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.

                  1. dev_meme 2y

                    ++ 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

                    1. @Araalith 2y

                      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...

                  2. @callofvoid0 2y

                    instance?.Dispose what is that question mark here? is that a special language?

                    1. dev_meme 2y

                      its pretty fresh js feature

                    2. dev_meme 2y

                      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

                    3. @Araalith 2y

                      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)

                  3. dev_meme 2y

                    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

                  4. dev_meme 2y

                    let a = 1; let b = a; a++; and in this case ++ is ok

  6. @Sp1cyP3pp3r 2y

    i want to believe ++inc

  7. @DavidGarciaCat 2y

    nice !! just another reason to avoid learning Swift

  8. @v1lezor 2y

    for (int i = 0; i < size; i++) vs for (int i = 0; i < size; i += 1) it hurts my eyes

    1. @knzev 2y

      There is no C-style loop in swift 🙂

      1. @knzev 2y

        for i in 0..<size

  9. @Box_of_the_Fox 2y

    Meanwhile android devs using kotlin:

  10. @adozzer 2y

    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)

    1. @adozzer 2y

      And I believe it is more readable also, as you get the idea behind the code

    2. @purplesyringa 2y

      append would cause reallocations though

  11. @Anfid 2y

    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?

    1. @purplesyringa 2y

      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.

      1. @Anfid 2y

        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++

        1. @purplesyringa 2y

          idk I miss *dst++ = *src++

          1. @Anfid 2y

            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?

    2. @Araalith 2y

      It has never been confusing to me. I just treat ++/-- as shortcuts for simple functions.

  12. @purplesyringa 2y

    no, that's UB

  13. @adozzer 2y

    That is the essence of python

  14. @picatsv 2y

    https://github.com/apple/swift-evolution/blob/main/proposals/0004-remove-pre-post-inc-decrement.md couldve at least linked the full reasoning...

  15. dev_meme 2y

    popular eslint configs in js are afraid too of using ++ and --

  16. @Saeid025 2y

    So many languages don't actually have these operators... No I'm not talking about python... Take rust for example

  17. dev_meme 2y

    and you are using var in your project. wtf?

  18. dev_meme 2y

    ohh. is it c#?

  19. @intbyte20 2y

    This syntax is also used in swift

Use J and K for navigation