-1

I just started with scala 3 and while playing around I found out, that there is a "^"-operator.

I just have no clue what it does and the outputs it produces are also not really telling.

I tried finding it on google or in the docs, but aside from one mentioning I couldn't find anything.

https://docs.scala-lang.org/tour/operators.html

I also tried understaning the outputs, maybe you can make more sense of it:

@main def foo() :Unit = {
  var i = 0
  while i < 10 do {
    println(s"$i -> ${i^2}")
    i += 1
  }
}

Output:

0 -> 2
1 -> 3
2 -> 0
3 -> 1
4 -> 6
5 -> 7
6 -> 4
7 -> 5
8 -> 10
9 -> 11

More Outputs for different numbers after the ^ using i from 0 through 5:

i ^2 ^3 ^4 ^5
0 2 3 4 5
1 3 2 5 4
2 0 1 6 7
3 1 0 7 6
4 6 7 0 1
5 7 6 1 0
Sören
  • 1,803
  • 2
  • 16
  • 23
  • 1
    The question is marked as duplicate with a wrong link. When you put something after an Int, you are calling a method of the Int class. It happens the same for almost anything. So, depends on which instance you have on the left, is the method that will be executed. In the case of the Int, it's doing a XOR operation [Int ^](https://dotty.epfl.ch/api/scala/Long.html#^-fffff0ab) – Gastón Schabas Apr 25 '23 at 19:28
  • 1
    This is not only from scala 3. Scala 2 does the same [Int ^](https://www.scala-lang.org/api/current/scala/Int.html#^(x:Int):Int) – Gastón Schabas Apr 25 '23 at 19:30
  • 1
    So, there is no exactly an operator like other languages such as Java. You can also define a method named `^` in your custom class and then call it. What `^` is going to do, depends on the object – Gastón Schabas Apr 25 '23 at 19:34
  • 1
    [This thread - the double circumflex operator in scala](https://stackoverflow.com/questions/18889375/the-double-circumflex-operator-in-scala) could be a more acurrate link to show as duplicate – Gastón Schabas Apr 25 '23 at 19:37
  • Absolutely right @GastónSchabas, my bad as I didn't spend enough time to find a better duplicated link. – Gaël J Apr 25 '23 at 21:02
  • 2
    See [abstract def ^(x: Int): Int](https://www.scala-lang.org/api/current/scala/Int.html#^(x:Int):Int) – Mark Rotteveel Apr 26 '23 at 15:43
  • 1
    @GastónSchabas: We cannot show that double circumflex Question as a duplicate target because it lacks an upvoted Answer. I think this should be answered unless a valid dup target is available. – hardmath Apr 29 '23 at 19:10

1 Answers1

0

In scala, there isn't something like operators. You have objects and these ones have methods. In the oficial docs of scala where it talk about operators says

In Scala, operators are methods. Any method with a single parameter can be used as an infix operator. For example, + can be called with dot-notation:

Methods can be named with any name like the followings (of course there are naming conventions)

object DifferentNamesForMethods {
  def +(i: Int) = ???
  def $(i: Double) = ???
  def `class`(a: String, b: Boolean = ??? // you can use reserved words but you need to put them between backtics
  def `a name with spaces`(x: List[Int) = ???
}

When you are doing:

val a = b + c

what you are doing is

val a = b.+(c)

which means, you are invoking the method of an object that is named + (same for *, -, /). Backing to your question, based on your example

@main def foo() :Unit = {
  var i = 0
  while i < 10 do {
    println(s"$i -> ${i^2}") // here is where the `^`is being used
    i += 1
  }
}

Knowing that the variable i is of type Int, you are calling the method named ^ from the abstract final classInt extends AnyVal. As you can see in the description of the method: Returns the bitwise XOR of this value and x., which means you are doing an XOR operation at bit level between the instance of the object Int and the parameter received in the ˆ method. This will be translated as

println(s"$i -> ${i.^(2)}")

That's why you are getting those outputs. If you are using an IDE, it should show you the scaladoc of the method or even you would be able to browse the code.


offtopic

the piece of code you shared, can be rewritten in a more functional way without using variables that can be mutated

@main def foo() :Unit = {
  (1 until 10).foreach(i => println(s"$i -> ${i^2}"))
}
Gastón Schabas
  • 2,153
  • 1
  • 10
  • 17