147

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

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99
Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
  • 6
    I think this question if out of the scope of stackoverflow mainly because all the accepted proposal for the swift evolution can be found in Github, you can read more about the why of this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0004-remove-pre-post-inc-decrement.md – Victor Sigler Feb 02 '16 at 16:19
  • 2
    To be fair the traditional for loop is being removed as well, so not quite the best example. – Joe Feb 02 '16 at 16:20
  • @VictorSigler thx for response but is it possible to use for loops in this way? – Oleg Gordiichuk Feb 02 '16 at 16:20
  • @Joe hmm thx for the response – Oleg Gordiichuk Feb 02 '16 at 16:21
  • 7
    I'm seriously considering just going back to Objective-C. It's not worth trying to keep up with all the changes to Swift. – Greg Brown Feb 02 '16 at 16:22
  • 3
    @OlegGordiichuk It's the thing the for-loops as the C-style would be removed too, see this https://github.com/Vkt0r/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md so you don't need use more the `++` and `--` operators – Victor Sigler Feb 02 '16 at 16:22
  • @GregBrown there are more changes to come. I am sticking with Obj-C for now. Nothing has forced me to move but I am also keeping an eye on what's going on. This particular change was made to be in keeping with the design of the language and also because of the redundancy (and confusion) in using ++ and --. – Fogmeister Feb 02 '16 at 16:25
  • 2
    I'm reviewing the proposed changes now. I'm really disappointed that Swift still seems to be in a state of flux. It makes it very difficult to seriously consider Swift as a viable option for app development. – Greg Brown Feb 02 '16 at 16:27
  • 2
    @GregBrown it's only a couple of years old. Of course it is still in a state of flux. – Fogmeister Feb 02 '16 at 16:29
  • 10
    There are too many breaking changes for my taste. I'm all for improvments, but I don't really want to spend my time rewriting substantial portions of my codebase every time an Xcode point release comes out. – Greg Brown Feb 02 '16 at 16:32
  • 1
    @GregBrown exactly my point. You seem to be arguing against me even though I'm agreeing with you. Yes, Swift is changing. It's new, of course it's changing. Yes, this means that some things written in Swift will break until Swift becomes more stable. So don't write anything in Swift that will be affected by Swift breaking. There is nothing forcing anyone to use Swift and drop Obj-C. That will be true for several years – Fogmeister Feb 02 '16 at 16:38
  • @GregBrown again you are saying that you can't tell when Swift is going to change and prefer Objective-C. Can you not see that you are creating your own arguments and knocking them down at the same time. There is no issue here. If you can't rely on Swift and prefer Objective-C then just use Objective-C. Am I the only one seeing the cyclic nature of your own arguments? Oh well. Never mind. :-? – Fogmeister Feb 02 '16 at 16:50
  • 4
    @Fogmeister I'm not sure how I could be any clearer. I'd prefer to use Swift, but I don't feel like it is stable enough. I've worked extensively with other languages in the past and have never run into so many breaking changes in such a short period of time. I feel like Apple wants us all to adopt Swift, but they are making it more difficult than it should be. – Greg Brown Feb 02 '16 at 16:55
  • 1
    It sucks how the `--` looks like an m-dash on the question title. Should we edit it and insert a (syntactically incorrect) space between both `-`s? – Nicolas Miari Apr 06 '16 at 02:05
  • Swift is one big mess. Whoever wrote it didn't give a hoot about those who are learning it and/or using it. I learned C, Perl, Java and c# by running sample codes and playing with it. A large majority of the sample codes out there are now junk with swift 3. The `convert` code is a joke. In one sample code I had 10s of errors. Apple should hire folks like Eric Lippert (one of the gods of .net) and others who understand that you cannot just re-write the book and pull the rug from under people because you felt like it. – Zuzlx Nov 29 '16 at 23:30
  • @NicolasMiari fixed it. – Loïc Faure-Lacroix May 26 '17 at 18:21
  • Just starting to look at Swift and on writing my second small program was surprised to see that this has gone from the language. The wrong decision IMHO. While changes to a language design are often worthwhile, breaking-changes that achieve no quantifiable object probably never are. I accept that others may see it differently, but I don't think that the reasons given justify the removal. The concepts are simple and the feature saves code. -- this change for me. The only reason for the change appears to be - Chris didn't like it. Sounds very purist to me. – Brian Oh Jun 29 '20 at 02:09

12 Answers12

221

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?"

Community
  • 1
  • 1
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • 56
    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 ... – user3441734 Feb 02 '16 at 17:56
  • 6
    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. – Echelon Apr 01 '16 at 11:53
  • 3
    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 Apr 06 '16 at 02:07
  • 10
    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. – csga5000 May 13 '16 at 09:50
  • 4
    @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. – overactor Jun 02 '16 at 19:46
  • 1
    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. – Ryan Poolos Jun 20 '16 at 14:47
  • 2
    @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 Jun 21 '16 at 15:52
  • @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. – csga5000 Jun 21 '16 at 15:54
  • Point 4: Is there really a better replacement for `--` in a C-style decrementing loop? ;-) – Amin Negm-Awad Jul 11 '16 at 15:46
  • 2
    There is one: `for i in (0.. – Code Different Jul 11 '16 at 15:50
  • 2
    Chris Lattner doesn't like it. :D – Felipe Andrade Sep 04 '16 at 14:14
  • 3
    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. – Agustí Sánchez Sep 25 '16 at 17:41
  • I think the only really valid argument is point 3 (and 4 to some extent) - the rest is just subjective preference – Joseph Junior Sfeir Oct 27 '16 at 08:35
  • #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. – clearlight Dec 04 '16 at 15:59
  • 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 ... – Bogdan Feb 10 '17 at 14:09
  • `i += 1` returns `Void`, which is the most important point. So, `++i` and `i++` return `Void`, too. – DawnSong Sep 28 '18 at 03:44
  • 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 – timeSmith Jan 16 '19 at 12:55
  • @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++. – Nicolas Miari Jan 16 '19 at 13:09
  • @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. – timeSmith Jan 17 '19 at 13:03
  • 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. – Neph Sep 30 '21 at 12:37
  • 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. – Azurlake Jan 04 '22 at 16:21
41

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
}
0101
  • 2,697
  • 4
  • 26
  • 34
  • 2
    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` – Alnitak May 16 '16 at 09:08
  • 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. – 0101 May 16 '16 at 11:33
  • 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` – Alnitak May 16 '16 at 11:35
  • 1
    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. – 0101 May 16 '16 at 12:19
  • 4
    You can use `defer` for this, too. `defer { x += 1 }; return x` – Tim Vermeulen Sep 08 '16 at 17:56
  • Can you share the script that created this? or you did it yourself? :) – Orkhan Alikhanov Jul 31 '17 at 19:11
  • 5
    why not use generics and write this in a few lines? – μολὼν.λαβέ Nov 18 '17 at 21:06
  • 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. – noamtm Jul 26 '18 at 09:50
  • `i += 1` returns `Void`, which is the most important point. So, `++i` and `i++` return `Void`, too. – DawnSong Sep 28 '18 at 03:43
  • @DawnSong Why would they? When Swift had `++` and `--` they did not return `Void`. So why now? – JeremyP Jan 15 '19 at 15:13
  • @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. – JeremyP Jan 15 '19 at 15:15
  • @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. – DawnSong Jan 15 '19 at 19:10
  • @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? – JeremyP Jan 15 '19 at 20:27
  • @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? – DawnSong Jan 17 '19 at 08:41
  • @DawnSong There's no law that says that `++i` must be identical to `i += 1`. Indeed, in Swift 1 and 2, it was not. – JeremyP Jan 17 '19 at 11:16
  • @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. – DawnSong Feb 14 '19 at 12:30
  • @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. – JeremyP Feb 14 '19 at 21:40
  • @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? – DawnSong Feb 15 '19 at 09:46
  • @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 `++`. – JeremyP Feb 19 '19 at 18:09
22

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!

Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177
Sohil R. Memon
  • 9,404
  • 1
  • 31
  • 57
8

For Swift 4, you can restore the ++ and -- operators as extensions for Int and other types. Here is an example:

extension Int {
   @discardableResult
   static prefix func ++(x: inout Int) -> Int {
        x += 1
        return x
    }

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

    @discardableResult
    static prefix func --(x: inout Int) -> Int {
        x -= 1
        return x
    }

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

It works the same way for other types, such as UIInt, Int8, Float, Double, etc.

You can paste these extensions in a single file in your root directory, and they will be available for use inside all of your other files there. It works perfectly, if you check it out in a playground.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
7

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.

Jay Mehta
  • 1,511
  • 15
  • 20
  • 9
    Clean? Look at this callback hell and call it clean? I disagree... And I'd add: leave the ++ & -- alone – mcatach Mar 24 '16 at 15:50
  • 23
    something like `...for i in 0.stride(to: 10, by: 2)...` or `...for i in (1...10).reverse()...` is clean?! – mad_manny Apr 01 '16 at 11:44
  • 6
    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. – Adrian Bartholomew May 10 '16 at 14:31
  • 3
    Try parsing json and swift and tell me how clean it is. – nickthedude Oct 12 '16 at 19:24
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

Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177
5

Here is a generic version of some of the code posted so far. I would voice the same concerns as others: it is a best practice to not use these in Swift. I agree that this could be confusing for those reading your code in the future.

prefix operator ++
prefix operator --
prefix func ++<T: Numeric> (_ val: inout T) -> T {
    val += 1
    return val
}

prefix func --<T: Numeric> (_ val: inout T) -> T {
    val -= 1
    return val
}

postfix operator ++
postfix operator --
postfix func ++<T: Numeric> (_ val: inout T) -> T {
    defer { val += 1 }
    return val
}

postfix func --<T: Numeric> (_ val: inout T) -> T {
    defer { val -= 1 }
    return val
}

This can also be written as an extension on the Numeric type.

Doghound
  • 129
  • 1
  • 4
  • 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. – Devin Lane Sep 26 '19 at 02:43
4

From the docs:

The increment/decrement operators in Swift were added very early in the development of Swift, as a carry-over from C. These were added without much consideration, and haven't been thought about much since then. This document provides a fresh look at them, and ultimately recommends we just remove them entirely, since they are confusing and not carrying their weight.

Dániel Nagy
  • 11,815
  • 9
  • 50
  • 58
  • In other words this operation is too expensive to be used ? – Oleg Gordiichuk Feb 02 '16 at 16:18
  • 2
    https://github.com/apple/swift-evolution/blob/master/proposals/0004-remove-pre-post-inc-decrement.md#disadvantages-of-these-operators here you can read about it, but it's not because it's expensive, but rather language design. – Dániel Nagy Feb 02 '16 at 16:22
  • So as i andersen Swift going to drop support of the C-style features – Oleg Gordiichuk Feb 02 '16 at 16:25
  • @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. – Fogmeister Feb 02 '16 at 16:27
  • @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. – mah Feb 02 '16 at 16:27
  • 2
    @OlegGordiichuk well I would say they want to emphasize that Swift is not a superset of C unlike Objective-C. – Dániel Nagy Feb 02 '16 at 16:32
  • 1
    @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". – Fogmeister Feb 02 '16 at 16:35
  • @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? – mah Feb 02 '16 at 16:41
  • @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. – Fogmeister Feb 02 '16 at 16:47
  • @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. – mah Feb 02 '16 at 16:56
0
var value : Int = 1

func theOldElegantWay() -> Int{
return value++
}

func theNewFashionWay() -> Int{
let temp = value
value += 1
return temp
}

This is definitely a downside, right?

outcast
  • 548
  • 1
  • 6
  • 20
  • 5
    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... – Nicolas Miari Mar 23 '16 at 10:04
0

Since you never really work with pointers in Swift, it kinda makes sense to remove the ++ and -- operators in my opinion. However if you can't live without, you may add these Swift 5+ operator declarations to your project:

@discardableResult
public prefix func ++<T: Numeric>(i: inout T) -> T {
    i += 1
    return i
}

@discardableResult
public postfix func ++<T: Numeric>(i: inout T) -> T {
    defer { i += 1 }
    return i
}

@discardableResult
public prefix func --<T: Numeric>(i: inout T) -> T {
    i -= 1
    return i
}

@discardableResult
public postfix func --<T: Numeric>(i: inout T) -> T {
    defer { i -= 1 }
    return i
}
LimeRed
  • 1,278
  • 13
  • 18
0

In a language without semicolons, it can be ambiguous. Is it a prefix or postfix operator?

Consider:

var x = y
++x

A human reads ++x but a parser could read this as y++.

doug94028
  • 125
  • 4
  • 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. – Chris Walken Mar 16 '22 at 19:58
-3

In Swift 4.1 it could be achieved this way:



    prefix operator ++
    postfix operator ++
    extension Int{
        static prefix func ++(x: inout Int)->Int{
            x += 1
            return x
        }
        static postfix func ++(x: inout Int)->Int{
            x += 1
            return x-1
        }
    }
    //example:
    var t = 5
    var s = t++
    print("\(t) \(s)")


Notice that despite the fact that this solution in similar to previous solutions in this post, they don't work anymore in Swift 4.1 and this example does. Also notice that whomever above mentions that += is a replacement for ++ just don't fully understand the operator as ++ combined with assignment is actually two operations, hence a shortcut. In my example: var s = t++ does two things: assign the value of t to s and then increment t. If the ++ comes before, it's the same two operations done in reversed order. To my opinion, the reasoning of Apple about why to remove this operator(mentioned in previous answers), is not only false reasoning but furthermore I believe it is a lie and the true reason is that they couldn't make their compiler handle it. It gave them troubles in previous versions so they gave up. The logic of "too complicated to understand operator, hence removed" is obviously a lie because Swift contains operators far more complicated and much less useful which were not removed. Also, the vast majority of programming languages has it. JavaScript, C, C#, Java, C++ and so many more. Programmers happily use it. Whomever it is too difficult to understand this operator for, they and only they should do the += (or perhaps s = s + 1 if += is too complexed as well).

The strategy behind Swift is simple: Apple believes the programmer is dumb and therefore should be treated accordingly.

The truth is that Swift, launched at September 2014 was supposed to be somewhere else by now. Other languages grew up much faster.

I can list many major mistakes in the language, from serious ones: such as arrays pasted by value and not by reference, to annoying ones: variadic parameters functions can't accept an array which is the whole idea behind it. I don't think that Apple's employees are even allowed to look at other languages such as Java so they don't even know that Apple is light years behind. Apple could have adopted Java as a language but these days, challenge is not technology, but ego is. If they would have opened IntelliJ to write some Java, they would for sure close their business understanding that at this point, they can't and won't catch up ever.

Elad Lavi
  • 633
  • 5
  • 7