News for hackers. Stuff that matters.
Re:Java's records, Lombok's data, and Kotlin's data classes by lmm on Friday May 07, 2021 @09:35PM (#27082799)
Implicits are one feature that replace many features in other languages (Kotlin has probably 5 or 6 special features that each do limited subsets of what implicits can do, and still misses important parts of their functionality). There is some legitimate criticism to be made of Scala implicits (though I have yet to see a better alternative), but "too many features" isn't it.
Re:Java's records, Lombok's data, and Kotlin's data classes by lolinder on Friday May 07, 2021 @09:56PM (#27082935)
What Kotlin features do implicits serve to replace? I'm new to Scala and am having trouble imagining when I'd want to use an implicit, so I'm genuinely curious.
Re:Java's records, Lombok's data, and Kotlin's data classes by lmm on Friday May 07, 2021 @10:05PM (#27082987)
Off the top of my head: Extension methods. "with" contexts. Scope functions (by letting you write your own). Many of the things done with kapt (e.g. typeclasses, not that there's a good way to do them in Kotlin). Spring-style autowiring (not part of Kotlin proper, but seemingly the idiomatic way to use it). The magic last parameter lambda syntax thing (by letting you implement the magnet pattern).
Re:Java's records, Lombok's data, and Kotlin's data classes by beerbajay on Saturday May 08, 2021 @10:57AM (#27087699)
Scala implicits are used in a few different places, predominantly in library code where they can for example be used to derive instances of type classes. e.g. in circe:

  import io.circe.syntax._
  List(1, 2, 3).asJson
Where `asJson` requires an instance of an `Encoder`[1] and this Encoder can be derived with the help of implicits.

For you as a normal user, the two common places where you might use implicits are (1) for implicit classes providing syntactic sugar:

  // original
  def doSomething(a: A): B = ???
  val a: A = ???
  val b = doSomething(a)

  // with implicits
  implicit class AImplicits(a: A) {
    def doSomething: B = ???
  }
  val a: A = ???
  val b = a.doSomething
and for (2) implicit conversions. These are a foot-gun, so should be used in limited circumstances. At work, we use case classes in data pipelines then convert these to avro classes on save; there's lots of ways to do this, but as an example if you have an `Optional[Int]` and your avro constructor requires a nullable java `Integer` then `JavaConverters` won't save you and you'll need something like:

  implicit def optIntToInteger(optI: Option[Int]): java.lang.Integer = optI.map(Int.box).orNull
[1] https://circe.github.io/circe/api/io/circe/syntax/package$$E...