Shashi Shankar
Shashi Shankar

Reputation: 809

Scala Implicit classes

As per documentation https://users.scala-lang.org/t/sip-13-implicit-classes-scala-documentation/705, use case of implicit class is
"A new language construct is proposed to simplify the creation of classes which provide extension methods to another type."
This require creation of new class, respective function and import.
The same can be achieved by creating Utils classes with static method. I am unable to understand what additional benefit implicit classes are adding here which can't be achieved by Utils classes with static method.

Upvotes: 0

Views: 627

Answers (3)

Alexey Romanov
Alexey Romanov

Reputation: 170859

One concrete benefit:

foo.bar().aMethodAddedByImplicitClass().baz()

makes the order of operations clearer than the equivalent using static methods:

UtilsClass.aMethod(foo.bar()).baz()

Upvotes: 1

Ryan Stull
Ryan Stull

Reputation: 1096

You don't gain any "power" per se, the ability to do something you couldn't do before; however implicit classes offer something static methods in a Utils class don't, clarity.

Say you want to do something, like check if a string contains at least one of several different choices. You could implement this functionality like this:

object Hello {

    def main(args: Array[String]): Unit = {

        val str =
            """
              |Hello Mary,
              |
              |How's it going? I hope everything is going well with you.
              |
              |Bye!
            """.stripMargin

        println( StrUtils.containsOneOf(str,"Good","well","once","later"))
    }

}

object StrUtils {

    def containsOneOf(stringToCheck: String,strings: String*): Boolean = {
        strings.exists(stringToCheck.contains(_))
    }
}

Which would work, however it also looks a bit clunky. If we use implicit classes, we could make it look like this functionality was part of the String class all along.

object Hello {

    def main(args: Array[String]): Unit = {

        val str =
            """
              |Hello Mary,
              |
              |How's it going? I hope everything is going well with you.
              |
              |Bye!
            """.stripMargin

        println( str.containsOneOf("Good","well","once","later"))
    }

    implicit class StringUtils(s: String) {
        def containsOneOf(strings: String*): Boolean = {
            strings.exists(s.contains(_))
        }
    }

}

I believe the second example is a lot clearer and once you start building up complicated expressions, this kind of syntax can really help.

Side Note

Since (almost) all programming languages are Turing complete, meaning they can be used to compute anything a Turing machine can, they are in a sense "equally powerful". So how then, given that our languages are equally powerful, should we judge a programming language? I actually would argue that one of the primary metrics of how good a programming language is, is it's ability to maintain legibility as complexity increases. Languages that don't have a clear orthogonal base of features which can be combined, tend to end up with a large definition (i.e. lots of edge cases), and end up being more confusing to work in.

This feature's, implicit classes, primary benefit is to helps us to maintain the legibility of our code.

Upvotes: 6

Pavel
Pavel

Reputation: 1539

I would make assumption your question is specifically related to implicit case classes.

Implicit case classes extend your DSL with syntax you prefer or like to use, i.e:

case class Rectangle(w: Int, h : Int)

implicit class RectangleMaker(w : Int) {
  def x(h: Int) = Rectangle(w, h)
}

val myRec = 3 x 4

Code which compiler will generate for you behind the scene:

implicit def RectangleMaker(w: Int) = new RectangleMaker(w)

Example from book: programming in Scala (3-rd edition).

Hope that helps,

Upvotes: 0

Related Questions