Why is infix operator in swift not working? - swift

My infix operator for powering isn't working. It adds or subtracts.
precedencegroup SquareSumOperatorPrecedence {
lowerThan: MultiplicationPrecedence
higherThan: AdditionPrecedence
associativity: left
assignment: false
}
infix operator ^: SquareSumOperatorPrecedence
func ^(lhs: Double, rhs: Double) -> Double {
return pow(lhs, rhs)
}
9 ^ 2// equals 81
// It gives me 11
I thought 9 ^ 2 would give me 81, but it gave me 11

^ is already defined as “bitwise XOR” operator for integer operands, and that is what 9 ^ 2 computes:
9 ^ 2 = 0b1001 ^ 0b0010 = 0b1011 = 11
(See Advanced Operators for more information about bitwise operators.)
You defined an operator for double operands, and that works as expected if you actually call it with Double values:
print(9.0 ^ 2.0) // 81

Related

My custom operator needs a precedence group?

So I have a custom operator ≈ that works fine when comparing one pair of numbers but fails when I try to compare more than one pair. The code snippet below can be thrown right into a playground to replicate the error.
infix operator ≈
func ≈ (lhs: Int, rhs: Int) -> Bool {
lhs < rhs + 80 && lhs > rhs - 80
}
let results = 100 ≈ 75 && 89 ≈ 78 //<-- `Adjacent operators are in unordered precedence groups 'DefaultPrecedence' and 'LogicalConjunctionPrecedence'`
I read the docs on it but did not receive much understanding on how to fix this error.
You either need to group your operands:
let results = (100 ≈ 75) && (89 ≈ 78)
Or define your new operator precedence:
precedencegroup CongruentPrecedence {
lowerThan: MultiplicationPrecedence
higherThan: AdditionPrecedence
associativity: left
}
infix operator ≈:CongruentPrecedence

Custom Operator Precedence Issue in Swift?

I'm trying to implement a custom infix power operator using the "^" character with the following code, but I'm getting unexpected results.
precedencegroup PowerPrecedence {
associativity: right
lowerThan: BitwiseShiftPrecedence
higherThan: MultiplicationPrecedence
}
infix operator ^ : PowerPrecedence
func^(lhs:Float,rhs:Float) -> Float {
return pow(lhs,rhs)
}
When I use the ^ operator in the following statement,
let x = 1 + 10 ^ Float(2)
I expect x to be 1 + (10^2) = 101, but x is (1+10)^2 = 121 instead. What am I missing?

What is the purpose of allowing infix operators to have no an associativity?

Question 1: What is the purpose of allowing infix operators to have no associativity? (Possibly someone can give an example of a custom operator where this is preferable over actually including some associativity?)
Question 2: Is it possible to set a default associativity for infix operators, used for operators that have none?
We can define a custom infix operator without entering any associativity for it, e.g.
/* no associativity */
infix operator +| {
precedence 140
}
/* left associativity */
infix operator *| {
associativity left
precedence 140
}
Now, one could assume that using an infix operator without associativity (+| above) next to one with associativity (*| above)---where both operators have same precedence---would behave the same way as if both operators had the same associativity. However, this is not the case
func +| (lhs: Int, rhs: Int) -> Int {
return lhs+rhs
}
func *| (lhs: Int, rhs: Int) -> Int {
return lhs*rhs
}
let a : Int = 1 +| 2 *| 3
/* Error: non-associative operator is adjacent to
operator of same precedence */
If we add associativity left to the definition of +| above, the code runs fine (as expected)
/* no associativity */
infix operator +| {
associativity left
precedence 140
}
// ...
let a : Int = 1 +| 2 *| 3
/* 9, OK ((1+2)*3 = 9) */
If I have a look at the native Swift operators (Cmd-click Swift in import Swift), I can't find a single infix operators that is without associativity.
Why are we allowed to define infix operators without associativity, is there a possible use for such operators? Is it possible to set a default associativity for infix operators, such that operators with associativity will behave as if having the default associativity?

Unary operator '++'

I am interested and beginning in Swift, but I can't fix that :
func countvalue(tableau : [String]){
var b : Int = 0
for var b in tableau {
b++ // Unary operator '++' cannot be applied to an operand of type #lvalue String'
}
print("Il y a \(b) valeurs dans ce tableau.")
}
The b in your loop is a different variable than the one outside the loop, and is masking it. Since tableau is an array of Strings, b in the loop is a String, and thus cannot be incremented.
I think what you want is this...
func countvalue(tableau : [String]){
var b : Int = 0
for _ in tableau {
// the values in the array are not used so just ignore them with _
b++ // Unary operator '++' cannot be applied to an operand of type #lvalue String'
}
print("Il y a \(b) valeurs dans ce tableau.")
}
But the value of b will be the same if you do...
var b = tableau.count
Except this is a lot more efficient as it does not have to iterate every value of the array.

How to define a list of functions of the same arity in Scala?

In the various Lisps, it's possible for me to create a sequence of functions as if they'd just been normal values:
(def ops [+ - * /])
Which I can then iterate through, again, as if they were just normal values:
(doseq [op ops] // (doseq (op ops) is like for (op <- ops) in scala
(println (op 1 2 3 4)))
Now, I've tried a few things in Scala, all of them failing:
scala> List(+, -, *, /)
<console>:1: error: illegal start of simple expression
List(+, -, *, /)
^
scala> List[Double => Double](+, -, *, /)
<console>:1: error: illegal start of simple expression
List[Double => Double](+, -, *, /)
^
scala> List[Double => Double](+_, -_, *_, /_)
<console>:8: error: not found: value *
List[Double => Double](+_, -_, *_, /_)
^
<console>:8: error: not found: value /
List[Double => Double](+_, -_, *_, /_)
^
So what's the correct procedure of defining a list of functions/operators in Scala?
The problem is that these functions are binary operators, i.e., they take two operands and return one. So you have to use:
List[(Double, Double) => Double](_ + _, _ - _, _ * _, _ / _)
In Scala, most value-level operators are actually unary instance methods (maybe all are, not sure if there are counterexmaples). So when you talk about, say, addition of two values of type Double, you're really referring to a method of the first value that takes the second value as a parameter. The familiar infix operator syntax is just sugar. In other words,
scala> 5.7 + 6.3
res0: Double = 12.0
is really just a nice shorthand for:
scala> 5.7.+(6.3)
res1: Double = 12.0
As #bluenote10 already mentioned, you can capture these operators by creating anonymous function that take both the first instance and its operand as parameters and returns the result of the + method:
scala> (lhs: Double, rhs: Double) => lhs + rhs
res2: (Double, Double) => Double = <function2>
Or as in #bluenote10's example, if the type can be inferred (like in a list with the type provided), you can use the nice underscore syntax:
scala> val doublePlus: (Double, Double) => Double = _ + _
doublePlus: (Double, Double) => Double = <function2>