Some numeric madness - swift

Recently I wrote some helper functions for standard math operations(+,-,*,/) to process statistics without retardation, so explicit cast of numerics are unneeded
Double(8)/Double(3) // can be written as 8/3
It worked without a hassle, until I spot some erroneous behavior of a division operator, that is:
func / <F: BinaryFloatingPoint, I: BinaryInteger>(lhs: F, rhs: I) -> F {
return lhs / F(rhs)
}
func / <F: BinaryFloatingPoint, I: BinaryInteger>(lhs: I, rhs: F) -> F {
return rhs / F(lhs)
}
let a = 10.0
let b: UInt8 = 8
print(a/b) //outputs 1.25
print(b/a) //THIS is where weird stuff shows because it outputs 1.25 as well, but should 0.8!!
Is there something I missing or could it be a bug?

It was I little skid with position of operands. The valid code is:
func / <F: BinaryFloatingPoint, I: BinaryInteger>(lhs: F, rhs: I) -> F {
return lhs / F(rhs)
}
func / <F: BinaryFloatingPoint, I: BinaryInteger>(lhs: I, rhs: F) -> F {
return F(lhs) / rhs
}
let a = 10.0
let b: UInt8 = 8
print(a/b) //1.25
print(b/a) //0.8

Related

inconsistent rules for operator overloading in swift

I'm seeing a strange difference in the way swift will overload + vs >:
protocol Value {
func get() -> Float
mutating func set(to:Float)
}
extension Float : Value {
func get() -> Float {
return self
}
mutating func set(to value:Float) {
self = value
}
}
func + (a:Value, b:Value) -> Float {
return a.get() + b.get()
}
func > (a:Value, b:Value) -> Bool {
return a.get() > b.get()
}
let a:Float = 1
let b:Float = 2
let c:Float = a + b //this works fine. Compiler calls Float + Float
let d = b > a //this causes infinite loop. Compiler recursively calls Value > Value
Any idea why the swift compiler is treating these cases differently?
The difference is that the standard library currently has a + overload defined directly on Float:
// TODO: These should not be necessary, since they're already provided by
// <T: FloatingPoint>, but in practice they are currently needed to
// disambiguate overloads. We should find a way to remove them, either by
// tweaking the overload resolution rules, or by removing the other
// definitions in the standard lib, or both.
extension ${Self} {
#_inlineable // FIXME(sil-serialize-all)
#_transparent
public static func + (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
var lhs = lhs
lhs += rhs
return lhs
}
// [...]
}
(where ${Self} will be substituted by Float, Double & Float80 upon gyb.py running)
When it comes to overload resolution, a (Float, Float) -> Float overload of + will win over a (Value, Value) -> Float overload when applied with Float operands, as the latter will require them to be converted from Float to Value.
However Float doesn't have a > overload defined directly on it; it's instead defined as a top-level generic function over FloatingPoint operands:
#_transparent
public func > <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
return rhs.isLess(than: lhs)
}
When it comes to overload resolution, your (Value, Value) -> Bool overload will win over this generic overload as overload resolution favours non-generic overloads (see the tangent in my answer here). Therefore you'll wind up recurring. You could fix this by making your overload of > generic over <T : Value>(T, T) -> Bool, but then it would no longer be applicable to heterogenous Value operands.
Assuming you want the operators to be applicable to heterogenous operands, one foolproof solution would be to dispatch the calls to > and + via Float's conformance to Numeric and Comparable by using nested generic functions. This can't recurse because neither (Value, Value) -> Float nor (Value, Value) -> Bool can satisfy the + and > requirements of these respective protocols.
func + (lhs: Value, rhs: Value) -> Float {
func add<T : Numeric>(_ lhs: T, _ rhs: T) -> T {
return lhs + rhs
}
return add(lhs.get(), rhs.get())
}
func > (lhs: Value, rhs: Value) -> Bool {
func greaterThan<T : Comparable>(_ lhs: T, _ rhs: T) -> Bool {
return lhs > rhs
}
return greaterThan(lhs.get(), rhs.get())
}
(Note we're doing this for + as well as >, as the + (Float, Float) -> Float overload may be removed in favour of a generic overload, which would cause the same problems as with >)
Another solution would be to avoid dispatching to > and + altogether, and instead just call the isLess(than:) method on Float and the += operator, mimicking the stdlib implementations:
func + (lhs: Value, rhs: Value) -> Float {
var lhsFloat = lhs.get()
lhsFloat += rhs.get()
return lhsFloat
}
func > (lhs: Value, rhs: Value) -> Bool {
return rhs.get().isLess(than: lhs.get())
}
Though the calling of += may be problematic if you implement an overload of it for (inout Value, Value) -> Void.

Deprecations to syntax such as ++, --, and C-style loops in preparation for the future Swift 3 release [duplicate]

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)")
}
A full explanation here from Chris Lattner, Swift's creator. I'll summarize the points:
It's another function you have to learn while learning Swift
Not much shorter than x += 1
Swift is not C. Shouldn't carry them over just to please C programmers
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)
Can be tricky to read and maintain, for eg, what's the value of x - ++x or foo(++x, x++)?
Chris Lattner doesn't like it.
For those interested (and to avoid link rot), Lattner's reasons in his own words are:
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.
Their expressive advantage is minimal - x++ is not much shorter than x += 1.
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.
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.
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 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?"
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
}
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!
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.
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.
The Fix-it feature of Xcode gives clear answer to this.
Replace ++ increment operator with old-fashioned value += 1 (short-hand operator) and -- decrement operator with value -= 1
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.
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.
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?
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
}
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++.
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.

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

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)")
}
A full explanation here from Chris Lattner, Swift's creator. I'll summarize the points:
It's another function you have to learn while learning Swift
Not much shorter than x += 1
Swift is not C. Shouldn't carry them over just to please C programmers
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)
Can be tricky to read and maintain, for eg, what's the value of x - ++x or foo(++x, x++)?
Chris Lattner doesn't like it.
For those interested (and to avoid link rot), Lattner's reasons in his own words are:
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.
Their expressive advantage is minimal - x++ is not much shorter than x += 1.
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.
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.
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 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?"
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
}
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!
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.
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.
The Fix-it feature of Xcode gives clear answer to this.
Replace ++ increment operator with old-fashioned value += 1 (short-hand operator) and -- decrement operator with value -= 1
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.
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.
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?
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
}
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++.
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.

Is it possible to add function definitions programmatically in swift

I'm creating a struct that holds 3 float values,
struct Col {
var r: Float
var g: Float
var b: Float
}
and I'd like to add a bunch of function definitions that are equivalent to the built in math functions, but that operate piecewise on the members of my struct
I can do it by hand, eg
func pow(a: Col, b: Col) -> Col {
return Col(r: pow(a.r, b.r), g: pow(a.g, b.g), b: pow(a.b, b.b))
}
but this is tedious and error prone.
What I'd like to do is create a function to turn the original math function into my Col version, so that I could call it like this:
defineColVersion(pow, noArgs: 2)
and it defines the new version, without overwriting the built in function that operates on Doubles
Is there any way to do this in Swift?
Thanks
I actually think this is exactly what you want:
func toCol(f: (Float, Float) -> Float) -> (Col, Col) -> Col {
return { a, b in
Col(r: f(a.r, b.r), g: f(a.g, b.g), b: f(a.b, b.b))
}
}
func toCol(f: Float -> Float) -> Col -> Col {
return { c in
Col(r: f(c.r), g: f(c.g), b: f(c.b))
}
}
let pow = toCol(Darwin.pow)
let sin = toCol(Darwin.sin)
let log = toCol(Darwin.log)
let a = Col(r: 0.4, g: 0.2, b: 0.7)
let b = Col(r: 0.3, g: 0.9, b: 0.3)
pow(a, b)
sin(a)
log(b)
The two overloaded functions toCol take a unary/binary function on Floats and returns a new function which does the same on your Col type. With those two, you can easily create a pow function for your Col type.
It is not possible to programmatically define new functions in a static language like Swift. What you can do, however, is to make a higher-kinded function:
func init(a: Col, b: Col, function: (Float, Float) -> Float) -> Col {
return self.init(r: function(a.r, b.r), g: function(a.g, b.g), b: function(a.b, b.b))
}
Col(Col(1, 2, 3), Col(3, 4, 5)) { $0 * $1 }
Col(Col(1, 2, 3), Col(3, 4, 5)) { pow($0, $1) }
func init(first: Col, second: Col, function: (Float, Float) -> Float ) {
newR = function(first.r,second.r)
newG = function(first.g,second.g)
newB = function(first.b,second.b)
return self.init(r:newR,g:newG,b:newB)
}
I'm not in a position to compile this so it probably has some errors but hopefully it will be useful. You would use it like so:
first = Col(r:1,g:2,b:3)
second = Col(r:1,g:2,b:3)
combined = Col(first:first,second:second) { pow($0,$1) }

YCombinator not working in Swift

I am trying to create a lambda function as such to get a factorial function but this throws a segmentation fault and errors out. How do I get this working in Swift. Please look at this video for reference on what I am trying to do http://www.confreaks.com/videos/1287-rubyconf2012-y-not-adventures-in-functional-programming
typealias f = () -> ()
typealias g = (Int) -> (Int)
typealias F = Any -> g
let y = { (gen: Any) -> g in
(gen as F)(gen)
}
let fact = y({ (gen: Any) -> g in
{ (n: Int) -> Int in
if n == 0 {
return 1
} else {
return n * (gen as F)(gen)(n - 1)
}
}
})
fact(10)
There's a great post by xiliangchen that walks through creating a Y-combinator in Swift. (Technically, this isn't a Y-combinator, since it is explicitly recursive, but it largely does what you want.) Here's an example of that Y function (stripped of its generic specification for clarity):
typealias G = Int -> Int
func Y (f: G -> G) -> G {
return {
(i: Int) -> Int in
f(Y(f))(i)
}
}
let factorial = Y { (f: G) -> G in
{ (n: Int) -> Int in
if n == 0 {
return 1
} else {
return n * f(n - 1)
}
}
}
factorial(5) // 120
For more on Y-combinators, you can look at this terrific (long) piece by Mike Vanier.
(Note: Using Any is kind of a mess -- I'd recommend steering clear of it whenever you can, especially since you don't need it in this case.)
You can implement a real (without explicit recursion) Y combinator using a recursive type, without any unsafe tricks (credits to Rosetta Code):
struct RecursiveFunc<F> {
let o : RecursiveFunc<F> -> F
}
func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
let r = RecursiveFunc<A -> B> { w in f { w.o(w)($0) } }
return r.o(r)
}
let factorial = Y { (f: Int -> Int) -> Int -> Int in
{ $0 <= 1 ? 1 : $0 * f($0-1) }
}
println(factorial(10))
Any doesn't really help because Any cannot represent function types.
Update: Starting in Xcode 6.1 beta 3, Any can represent function types, and your code compiles and works correctly.
This is an implementation in modern Swift that actually compiles under Swift 5.7. It has the proper modern closure syntax and declares as escaping the escaping closures.
import Foundation
struct RecursiveFunc<T> {
let o : (RecursiveFunc<T>) -> T
}
func Y<A, B>(f: #escaping (#escaping (A) -> B) -> (A) -> B) -> (A) -> B {
let r = RecursiveFunc<(A) -> B> { w in f { w.o(w)($0) } }
return r.o(r)
}
let fac = Y { (f: #escaping (Int) -> Int) in
{ $0 <= 1 ? 1 : $0 * f($0-1) }
}
func fact (_ n: Int) -> Int {
if n == 0 { return 1 }
else { return n * fact (n-1) }
}
print (fact(19))
print (fac (19))
NB: code pasted from a PlayGround