7

Below is the example program for Scala Implicit Class:

object Run {
   implicit class IntTimes(x: Int) {
      def times [A](f: =>A): Unit = {
         def loop(current: Int): Unit =

         if(current > 0){
            f
            loop(current - 1)
         }
         loop(x)
      }
   }
}

There is an other class that calls " 4 times println("hello")" as following, but I can not understand " 4 times println("hello")" mean?

object Demo {
   def main(args: Array[String]) {
      4 times println("hello")
   }
}

2 Answers2

10

4 times println("hello") roughly translates into:

val c = new IntTimes(4)
c.times(println("hello"))

That is, since there is an implicit class that takes an Int as its only argument, with a method times, doing 4.times implicitly instantiates the class with 4 as argument, and then invokes times on it.

StrikeR
  • 1,598
  • 5
  • 18
  • 35
Buhb
  • 7,088
  • 3
  • 24
  • 38
6

I also found this example way overly complicated to demonstrate Implicit Classes.

In a nutshell Implicit Classes overwrite other classes with new methods and properties.

In this example, it is overwriting Int to give it a method times. The times method takes a call-by-name parameter with a generic return type:

def times [A](f: =>A): Unit

Means f is a function that returns a generic type A.

When a call-by-name variable is used, it calls the function and becomes the return value. Inside times method it is using recursion to loop the call of f the number of times the integer it's called on.

In scala you can call methods by using a dot or space, and no need for brackets for parameters, so object.method(param1, param2) could be object method param1 param2

Hence the final call 4 times println("hello") is actually 4.times(println("hello"))

JasonY
  • 752
  • 10
  • 24
  • I am little confused here. I see that the method "times" takes a functional argument which does not take any input and returns A as output. But in the invocation of "times", the function println is passed which takes a string as i/p and returns Unit. This is just opposite to the signature. But this is working. Can someone please help me to understand. Thanks in advance! – user3103957 Nov 25 '19 at 15:44
  • It is useful to see that f has a call by name semantics so evaluation of f is delayed until the actual execution of the line in the body which calls f. The braces for the function body of `loop` have been skipped to show the body contains only the if statement. So, the method `times` just defines `loop` and calls it once. – sherminator35 Oct 21 '20 at 10:15