The "++" and "--" operators have been deprecated Xcode 7.3

72,052

Solution 1

A full explanation here from Chris Lattner, Swift's creator. I'll summarize the points:

  1. It's another function you have to learn while learning Swift
  2. Not much shorter than x += 1
  3. Swift is not C. Shouldn't carry them over just to please C programmers
  4. Its main use is in C-style for loop: for i = 0; i < n; i++ { ... }, which Swift has better alternatives, like for i in 0..<n { ... } (C-style for loop is going out as well)
  5. Can be tricky to read and maintain, for eg, what's the value of x - ++x or foo(++x, x++)?
  6. Chris Lattner doesn't like it.

For those interested (and to avoid link rot), Lattner's reasons in his own words are:

  1. These operators increase the burden to learn Swift as a first programming language - or any other case where you don't already know these operators from a different language.

  2. Their expressive advantage is minimal - x++ is not much shorter than x += 1.

  3. Swift already deviates from C in that the =, += and other assignment-like operations returns Void (for a number of reasons). These operators are inconsistent with that model.

  4. Swift has powerful features that eliminate many of the common reasons you'd use ++i in a C-style for loop in other languages, so these are relatively infrequently used in well-written Swift code. These features include the for-in loop, ranges, enumerate, map, etc.

  5. Code that actually uses the result value of these operators is often confusing and subtle to a reader/maintainer of code. They encourage "overly tricky" code which may be cute, but difficult to understand.

  6. While Swift has well defined order of evaluation, any code that depended on it (like foo(++a, a++)) would be undesirable even if it was well-defined.

  7. These operators are applicable to relatively few types: integer and floating point scalars, and iterator-like concepts. They do not apply to complex numbers, matrices, etc.

Finally, these fail the metric of "if we didn't already have these, would we add them to Swift 3?"

Solution 2

I realize that this comment doesn't answer the question nevertheless there may be people looking for a solution how to keep these operators working and such a solution can be found in the bottom. 😇

I personally prefer ++ and -- operators. I can't agree with the opinion that they are tricky or hard to manage. Once the developer understand what these operators do (and we are talking about pretty simple stuff) the code should be very clear.

In the explanation why the operators were deprecated is mentioned that their main use was in C-style for loops. I don't know about others but I personally don't use C-style loops at all and there are still many other places or situations when ++ or -- operator is useful.

I would like to also mention that varName++ returns a value so it can be used in the return whereas varName += 1 can not.

For any of you who would like to keep these operators working here is the solution:

prefix operator ++ {}
postfix operator ++ {}

prefix operator -- {}
postfix operator -- {}


// Increment
prefix func ++(inout x: Int) -> Int {
    x += 1
    return x
}

postfix func ++(inout x: Int) -> Int {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt) -> UInt {
    x += 1
    return x
}

postfix func ++(inout x: UInt) -> UInt {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int8) -> Int8 {
    x += 1
    return x
}

postfix func ++(inout x: Int8) -> Int8 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return x
}

postfix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return (x - 1)
}
prefix func ++(inout x: Int16) -> Int16 {
    x += 1
    return x
}

postfix func ++(inout x: Int16) -> Int16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return x
}

postfix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int32) -> Int32 {
    x += 1
    return x
}

postfix func ++(inout x: Int32) -> Int32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return x
}

postfix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int64) -> Int64 {
    x += 1
    return x
}

postfix func ++(inout x: Int64) -> Int64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return x
}

postfix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Double) -> Double {
    x += 1
    return x
}

postfix func ++(inout x: Double) -> Double {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float) -> Float {
    x += 1
    return x
}

postfix func ++(inout x: Float) -> Float {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float80) -> Float80 {
    x += 1
    return x
}

postfix func ++(inout x: Float80) -> Float80 {
    x += 1
    return (x - 1)
}

prefix func ++<T : _Incrementable>(inout i: T) -> T {
    i = i.successor()
    return i
}

postfix func ++<T : _Incrementable>(inout i: T) -> T {
    let y = i
    i = i.successor()
    return y
}

// Decrement
prefix func --(inout x: Int) -> Int {
    x -= 1
    return x
}

postfix func --(inout x: Int) -> Int {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt) -> UInt {
    x -= 1
    return x
}

postfix func --(inout x: UInt) -> UInt {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int8) -> Int8 {
    x -= 1
    return x
}

postfix func --(inout x: Int8) -> Int8 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return x
}

postfix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return (x + 1)
}
prefix func --(inout x: Int16) -> Int16 {
    x -= 1
    return x
}

postfix func --(inout x: Int16) -> Int16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return x
}

postfix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int32) -> Int32 {
    x -= 1
    return x
}

postfix func --(inout x: Int32) -> Int32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return x
}

postfix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int64) -> Int64 {
    x -= 1
    return x
}

postfix func --(inout x: Int64) -> Int64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return x
}

postfix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Double) -> Double {
    x -= 1
    return x
}

postfix func --(inout x: Double) -> Double {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float) -> Float {
    x -= 1
    return x
}

postfix func --(inout x: Float) -> Float {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float80) -> Float80 {
    x -= 1
    return x
}

postfix func --(inout x: Float80) -> Float80 {
    x -= 1
    return (x + 1)
}

prefix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    i = i.predecessor()
    return i
}

postfix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    let y = i
    i = i.predecessor()
    return y
}

Solution 3

Apple has removed the ++ and made it much simpler with the another old traditional way.

Instead of ++, you need to write +=.

Example:

var x = 1

//Increment
x += 1 //Means x = x + 1 

Similarly for decrement operator --, you need to write -=

Example:

var x = 1

//Decrement
x -= 1 //Means x = x - 1

For for loops:

Increment Example:

Instead of

for var index = 0; index < 3; index ++ {
    print("index is \(index)")
}

You can write:

//Example 1
for index in 0..<3 {
    print("index is \(index)")
}

//Example 2
for index in 0..<someArray.count {
    print("index is \(index)")
}

//Example 3
for index in 0...(someArray.count - 1) {
    print("index is \(index)")
}

Decrement Example:

for var index = 3; index >= 0; --index {
   print(index)
}

You can write:

for index in 3.stride(to: 1, by: -1) {
   print(index)
}
//prints 3, 2

for index in 3.stride(through: 1, by: -1) {
   print(index)
}
//prints 3, 2, 1

for index in (0 ..< 3).reverse() {
   print(index)
}

for index in (0 ... 3).reverse() {
   print(index)
}

Hope this helps!

Solution 4

Chris Lattner has gone to war against ++ and --. He writes, “Code that actually uses the result value of these operators is often confusing and subtle to a reader/maintainer of code. They encourage “overly tricky” code which may be cute, but difficult to understand….While Swift has well defined order of evaluation, any code that depended on it (like foo(++a, a++)) would be undesirable even if it was well-defined…these fail the metric of “if we didn’t already have these, would we add them to Swift 3?””

Apple wanted to keep swift a clean, clear, non-confusing and straight-to-the-point language. And so they deprecated ++ and -- keyword.

Solution 5

Screenshot for warning

The Fix-it feature of Xcode gives clear answer to this.

Solution to warning

Replace ++ increment operator with old-fashioned value += 1 (short-hand operator) and -- decrement operator with value -= 1

Share:
72,052
Oleg Gordiichuk
Author by

Oleg Gordiichuk

I am mobile apps developer.

Updated on September 09, 2021

Comments

  • Oleg Gordiichuk
    Oleg Gordiichuk over 2 years

    I am looking at Xcode 7.3 notes and I notice this issue.

    The ++ and -- operators have been deprecated

    Could some one explain why it is deprecated? And am I right that in new version of Xcode now you going to use instead of ++ this x += 1;

    Example:

    for var index = 0; index < 3; index += 1 {
        print("index is \(index)")
    }
    

    Screenshot for warning

  • Oleg Gordiichuk
    Oleg Gordiichuk about 8 years
    In other words this operation is too expensive to be used ?
  • Dániel Nagy
    Dániel Nagy about 8 years
    github.com/apple/swift-evolution/blob/master/proposals/… here you can read about it, but it's not because it's expensive, but rather language design.
  • Oleg Gordiichuk
    Oleg Gordiichuk about 8 years
    So as i andersen Swift going to drop support of the C-style features
  • Fogmeister
    Fogmeister about 8 years
    @OlegGordiichuk no, they are not "dropping C-style features". They are designing a new language and get to decide what fits and what doesn't. If a C-style function doesn't fit then they will drop it as there are better alternatives that match the language they are developing.
  • mah
    mah about 8 years
    @OlegGordiichuk It seems to me that swift's design is really not oriented towards existing developers (or those with passion towards being developers) but rather towards those that may not have the inclination to be developers -- as a way of enabling good design from people that don't have the developer thought process. This is certainly not to disparage the many excellent developers that have decided to move towards the language! It's just my opinion that those developers are not the language's target audience.
  • Dániel Nagy
    Dániel Nagy about 8 years
    @OlegGordiichuk well I would say they want to emphasize that Swift is not a superset of C unlike Objective-C.
  • Fogmeister
    Fogmeister about 8 years
    @mah a lot of what you said just doesn't make sense at all. "Not oriented towards existing developers" in what way? In the same way that Java is not oriented towards PHP developers? "oriented towards those that may not have the inclination to be developers"? Yeah, because all those non-developers out there are biting the hand off with protocol oriented programming and generics. "A way of enabling good design" just take a look at SO, you will see that no programming language can "enable good design".
  • mah
    mah about 8 years
    @Fogmeister my opinion is primarily based on the oversimplification of things, including removal of pre/post operators like this - I don't find them confusing and while I may be under the "curse of knowledge", it's difficult for me to see how other developers would get confused by them. I agree, languages do not enable good design per se, but by removing features that developers have used for years successfully, the language certainly gets easier for non-developers to pick up. Apple benefits by having these newbies-to-development writing iDevice apps, so who do you think is their target?
  • Fogmeister
    Fogmeister about 8 years
    @mah like I said further above. They are designing the language from scratch. They are not taking what has been done before and changing it. x++ makes sense to me. But what is the value of x after this... x = x - ++x? It add complexity where it isn't needed. Why is x += 1 so much worse? Like the accepted answer said, it's primary use was in C-style for loops. But for loops have a much better implementation in Swift that doesn't require it so it is no longer needed. Your argument seems to come down to "I dont like it because it's not what I'm used to" Of course it isn't. Its a new language.
  • mah
    mah about 8 years
    @Fogmeister Your argument seems to come down to "I dont like it because it's not what I'm used to" is you reading far more into things than I've said.... I neither dislike nor like it; I'm highly neutral and I have no judgement about the language at all. I invite you to attack my opinion, but I prefer you to first take time to see what my opinion is, which is about the motivation of the language's simplification, not about the details of it. I don't see that you have anything to be so defensive about.
  • user3441734
    user3441734 about 8 years
    I thing, the real answer is number 6. That is OK, we (former C, Java, ... programmers) are flexible enough :-). Generally, for the real world, mutation, crossover and selection is enough. I, You and Cris too, we are all results of those three operators ...
  • Nicolas Miari
    Nicolas Miari about 8 years
    You mean elegant as in "you have to remember all the subtleties of the C programming language, otherwise it is not immediately obvious if the first call returns 1 or 2"? I think we can all spare a few extra lines of code in exchange for not spending several minutes scratching our heads trying to find a bug cause by a silly mistake...
  • mcatach
    mcatach about 8 years
    Clean? Look at this callback hell and call it clean? I disagree... And I'd add: leave the ++ & -- alone
  • mad_manny
    mad_manny about 8 years
    something like ...for i in 0.stride(to: 10, by: 2)... or ...for i in (1...10).reverse()... is clean?!
  • Echelon
    Echelon about 8 years
    Point 5: Those were always implementation-dependent in C, and no-one with any sense ever did them. Simply define the behaviour and we'll get used to it. Better than having to go back and change perfectly good old code for no real reason.
  • Nicolas Miari
    Nicolas Miari about 8 years
    I like point 3. You can't be shackled to the contract of legacy forever. I love C but you are creating a new programming language; makes sense to start with the slate as clean as you need it to be.
  • Nicolas Miari
    Nicolas Miari about 8 years
    They haven't replaced anything; += was there all along.
  • Sohil R. Memon
    Sohil R. Memon about 8 years
    @NicolasMiari Yeah just editing with the much better format
  • Sohil R. Memon
    Sohil R. Memon about 8 years
    @NicolasMiari Can you please check now?
  • Zigii Wong
    Zigii Wong about 8 years
    What about ++i and --i ?
  • Adrian Bartholomew
    Adrian Bartholomew almost 8 years
    I agree. The 'clean' argument is fundamentally contradictory wrt to the rest of Swift. Coming from Objective-C, which is objectively unclean, it's quite difficult to accept 'clean' as an Apple language goal.
  • csga5000
    csga5000 almost 8 years
    It's cause apple likes to force you to think like they do. I think it's perfectly fine and used anywhere you need to increment or decriment a variable. It's not something you "have to learn" you'll do fine without it. And #5 is just poorly written code, the likes of which I have never seen. So #6 it is. Depricating it is enough to make me scratch my head and do a google search, so thanks for wasting my time Chris.
  • Alnitak
    Alnitak almost 8 years
    I don't like your return (x - 1) for the postfix operators - IMHO's it's cleaner to maintain the semantics that they return (a copy of) the original value rather than what you get if you do x + 1 - 1
  • 0101
    0101 almost 8 years
    I don't like it either but I don't know about any other (better, cleaner) way of doing this. I don't fully understand your second point.
  • Alnitak
    Alnitak almost 8 years
    Well, I'd just do let y = x; x += 1; return y - my latter point is over concerns that there may be edge cases relating to overflow where (x + 1) - 1 != x
  • 0101
    0101 almost 8 years
    I see, I didn't want to do that just for the sake of creating another variable (or rather constant in this case). If we are talking about Int only then the result of (x + 1) will be overflown which will interrupt execution and therefore result - 1 won't be even ran. Other datatypes like Double for example, behave however differently so I need to investigate that.
  • overactor
    overactor almost 8 years
    @csga5000 That's quite a weak argument considering that you can just define the operator yourself if you really want to. It has nothing to do with apple wanting people to think like them. It simply doesn't fit the language. If the ++ didn't exist in C-style languages, no one in their right mind would look at the design of Swift 3.0 and think that a ++ operator would be a nice addition to it.
  • Ryan Poolos
    Ryan Poolos almost 8 years
    Also worth pointing out that #5 being poorly written code is still ALOT of the code we deal with. The new changes make that code impossible. No more poorly written code is better than some poorly written code.
  • csga5000
    csga5000 almost 8 years
    @overactor First of all, I made arguments against all the points made for it, and you're picking one item and calling it a weak argument. Of course you could define the operator, but I would not think it a good practice. It could cause greater confusion to other developers on the project. My biggest argument is that deliberately removing the feature that previously existed and served a reasonable purpose is pointlessly causing slight confusion and costs people like me a few minutes of my time.
  • csga5000
    csga5000 almost 8 years
    @RyanPoolos Like I said, I've never see code written like that. And I've worked with some pretty awful code bases written by other companies or other developers. Not all of my code has been beautiful either, but none of it abuses the ++ operator in a confusing fashion such as that.
  • Amin Negm-Awad
    Amin Negm-Awad almost 8 years
    Point 4: Is there really a better replacement for -- in a C-style decrementing loop? ;-)
  • Code Different
    Code Different almost 8 years
    There is one: for i in (0..<n).reverse() { ... }
  • Felipe Andrade
    Felipe Andrade over 7 years
    Chris Lattner doesn't like it. :D
  • Tim Vermeulen
    Tim Vermeulen over 7 years
    You can use defer for this, too. defer { x += 1 }; return x
  • Agustí Sánchez
    Agustí Sánchez over 7 years
    Those freaks at Apple are deleting useful features like the "++" operator and the headphone jack out of sectarian ideology. I don't see the guys behind Java and C# deleting the "++" operator, they have more common sense.
  • nickthedude
    nickthedude over 7 years
    Try parsing json and swift and tell me how clean it is.
  • Joseph Junior Sfeir
    Joseph Junior Sfeir over 7 years
    I think the only really valid argument is point 3 (and 4 to some extent) - the rest is just subjective preference
  • clearlight
    clearlight over 7 years
    #5 is the only worthwhile reason I can see at this point to drop it, since it was included in earlier versions of Swift and was otherwise fairly harmless. Most programmers are (or should be) familiar with the convenient ++ and -- operators. Annoyingly I can't do if (++pos % 3600 == origPos) { } anymore but need to create an extra line. So it's not purely a positive to remove it. It has advantages and disadvantages.
  • Bogdan
    Bogdan about 7 years
    They should have thought all the basic language details when they started it. You don't come with this change or any other changes in upcoming versions. It's bad enough to have to use frameworks where the API changes over a version increase, but to see this in a language syntax that's just ...
  • Orkhan Alikhanov
    Orkhan Alikhanov almost 7 years
    Can you share the script that created this? or you did it yourself? :)
  • μολὼν.λαβέ
    μολὼν.λαβέ over 6 years
    why not use generics and write this in a few lines?
  • noamtm
    noamtm almost 6 years
    Like you, I don't like that they are removed; however, I wouldn't use it because it will confuse future programmers (that don't even know Java and C) who will think it's a core language feature. It's better to go in the way guided by the language. Still... +1 for showing that it's possible.
  • DawnSong
    DawnSong over 5 years
    i += 1 returns Void, which is the most important point. So, ++i and i++ return Void, too.
  • DawnSong
    DawnSong over 5 years
    i += 1 returns Void, which is the most important point. So, ++i and i++ return Void, too.
  • JeremyP
    JeremyP over 5 years
    @DawnSong Why would they? When Swift had ++ and -- they did not return Void. So why now?
  • JeremyP
    JeremyP over 5 years
    @0101 Things have moved on a bit since you wrote this answer. You could probably remove a lot of duplication by using making the operators generic over the new numeric protocols. Also, the index versions will probably no longer work.
  • DawnSong
    DawnSong over 5 years
    @JeremyP If assignment has a value, so if (a = 5) is valid, and a = b++ + ++b is valid too. They are confusing and lack readability. That's why Swift prefers that a = 5 is a Void, instead of 5.
  • JeremyP
    JeremyP over 5 years
    @DawnSong Why do you believe that the fact that the assignment operators have Void type means that the ++ and -- operators should also have Void type?
  • timeSmith
    timeSmith over 5 years
    This isn't a new language, it's version 3; the slate is not clean; this is a breaking change to add a trivial language attribute. @nicolas-miari
  • Nicolas Miari
    Nicolas Miari over 5 years
    @timeSmith Swift is a new language. That they didn’t come around to doing “the right thing” until version 3, is merely incidential in my opinion. You don’t want to be another C++.
  • DawnSong
    DawnSong over 5 years
    @JeremyP As we know, ++i is identical to i+=1, so if the latter have a Void return type, why ++i needs a return type?
  • JeremyP
    JeremyP over 5 years
    @DawnSong There's no law that says that ++i must be identical to i += 1. Indeed, in Swift 1 and 2, it was not.
  • timeSmith
    timeSmith over 5 years
    @NicolasMiari you said "…creating a new programming language; makes sense to start with the slate as clean as you need it to be." But this was a backward-incompatible change, to a ubiquitous feature, when the language was several years old, and when the language was on its 3rd (or 4th) major release version (4th because there was an effectively-public beta). I wasn't saying every language should have increment operators. I was saying the specific argument, that the language was new, is invalid.
  • DawnSong
    DawnSong about 5 years
    @JeremyP If ++i is not identical to i += 1, it's really confusing. Why people love to confuse himself / herself? Swift loves simplicity, so I love Swift.
  • JeremyP
    JeremyP about 5 years
    @DawnSong No, it's not really confusing. They don't look the same so it's not confusing that they are not the same. If you get confused by this, Swift's generics model is going to be a bit of a shock.
  • DawnSong
    DawnSong about 5 years
    @JeremyP Generics are very useful. Maybe the feature is not complete, but it will be. Results of many expressions composed by ++ depend on the compiler's implementation. So, ++ is malicious. Am I clear?
  • JeremyP
    JeremyP about 5 years
    @DawnSong Generics are an incredible powerful feature even as they are now. But they can be very confusing until you grok them. As for ++ depending on the compiler implementation, there is only one compiler and it doesn't have ++.
  • Devin Lane
    Devin Lane over 4 years
    I added @discardableResult to each of these functions to silence the warning about the return value being unused; otherwise exactly what I was looking for.
  • Neph
    Neph over 2 years
    Using ++ displays the following error in Swift 5/Xcode 13: Cannot find operator '++' in scope; did you mean '+= 1'? - so they know that people are going to try to use it. I fully agree with csga5000, reason 8 is simply: "You better deal with it and think like we do, even when it's an inconvenience like pressing 3 different keys that are pretty far apart on the keyboard, instead of just pressing the same key twice". Fitting for a company that won't even let you delete a file by pressing the "del" key.
  • Azurlake
    Azurlake over 2 years
    It's all about thinking the way they like you to think. Not specific to the operator, but bending your mind much like when "you're holding it wrong". I can quickly come up with extremely difficult to "visually decode" valid swift code and that doesn't invalidate the syntax - just the same finding some poor examples of ++ or -- doesn't invalidate their use. They're just a tool. Use them wise and that's it - if they let you use them.
  • Chris Walken
    Chris Walken about 2 years
    Uhhh…. What about the \n that comes at the end of var x = y - pretty sure it wasn’t the first day on the job for the guy that wrote the Swift parser.