Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding infix method call and cons operator(::) in Scala

Tags:

I'm quite new to Scala programming language, and was trying something out stucked in my mind while I was following the lecture notes at here.

I think I couldn't really understand how cons operator works, here are some things I tried:

I've created a pseudo-random number generator, then tried to create a list of one random value:

scala> val gen = new java.util.Random gen: java.util.Random = java.util.Random@1b27332  scala> gen nextInt 3 :: Nil <console>:7: error: type mismatch;  found   : List[Int]  required: Int        gen nextInt 3 :: Nil                      ^ 

But it tried to pass List(3) to nextnt method. When i used paratheses, there was no problem

scala> (gen nextInt 3) :: Nil res69: List[Int] = List(1) 

I was curious about the execution order, so i created a function to check it

scala> def pr(i:Int):Int = { println(i); i } pr: (i: Int)Int  scala> pr(1) :: pr(2) :: pr(3) :: Nil 1 2 3 res71: List[Int] = List(1, 2, 3) 

As seen in outputs, execution order is the same as the order of appearance. Then I thought it might be about the 'nextInt' function, then I tried following:

scala> 1 + 2 :: Nil res72: List[Int] = List(3) 

It first executed addition, and after that cons is executed. So here is the question: What is the difference between gen nextInt 3 :: Nil and 1 + 2 :: Nil?

like image 979
ciuncan Avatar asked Jul 05 '10 19:07

ciuncan


People also ask

What is cons operator in Scala?

In Scala, List has an operator :: , which is known as the Cons operator. It is useful to add new elements at the beginning of the List . Here, Cons is short for construct the new List object.

What is Scala infix?

For a long time, Scala has supported a useful “trick” called infix operator notation. If a method takes a single argument, you can call it without the period after the instance and without parentheses around the argument.

How do operators work in Scala?

In Scala, all operators are methods. Operators themselves are just syntactic sugar or a shorthand to call methods. Both arithmetic addition (+) and String. charAt() are examples of infix operators.

What is the meaning of => in Scala?

=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .


1 Answers

There are two things of concern here: precedence and fixity. As sepp2k mentioned, this question on Stack Overflow explains the precedence, thought the rules, as quoted, are not complete enough, and there were very small changes from Scala 2.7 to Scala 2.8. Differences concern mostly operators ending in =, though.

As for fixity, almost everything in Scala is read left to right, which is what programmers are used to. In Scala, however, operators ending in : are read right to left.

Take, then, this example:

1 + 2 :: Nil 

First, precedence. What has most precedence, + or :? According to the table, + has precedence over :, so the addition is done first. Therefore, the expression is equal to this:

((1).+(2)) :: Nil 

Now there's no precedence conflict, but since :: ends in :, it has a diferent fixity. It is read right to left, therefore:

Nil.::((1).+(2)) 

On the other hand, in this:

gen nextInt 3 :: Nil 

The operator :: has precedence over nextInt, because : has precedence over all letters. Therefore, and remembering its fixity, it becomes:

gen nextInt Nil.::(3) 

Which then becomes

gen.nextInt(Nil.::(3)) 

At which point the error is obvious.

PS: I'm writing (1).+(2) instead of 1.+(2) because, at the time of this writing, 1. is interpreted as a double number, making 1.+(2) an infix expression adding the double 1.0 to 2. This syntax is deprecated as of Scala 2.10.0, and will probably not be present on Scala 2.11.

like image 123
Daniel C. Sobral Avatar answered Nov 06 '22 06:11

Daniel C. Sobral