0

Given a Java interface

interface Value {

  Value add(Value argument);

}

(since Java does not support symbols like + as method names), is it possible to define an alias method + to alias add such that, when the class is used from Scala one can write

  result = value1 + value2

instead of

  result = value1.add(value2)

or

  result = value1 add value2

The alias should apply automatically to all classes implementing the interface.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Christian Fries
  • 16,175
  • 10
  • 56
  • 67
  • I was going to suggest `scala.annotation.alpha` in Dotty, but that apparently doesn't work - it doesn't override the actual add method, but when an add method and an operator with the same alias are made, it says there's a double definition https://scastie.scala-lang.org/UvqrkDFjSXmp9yOYIRSNCg, which is weird – user May 25 '20 at 14:56
  • See this very similar question: https://stackoverflow.com/questions/33279472/use-scala-macros-to-generate-methods – user May 25 '20 at 15:43
  • @user you can't annotate Java interface with Scala macro annotation. – Dmytro Mitin May 25 '20 at 16:30
  • 1
    @DmytroMitin No, but you can annotate Scala classes implementing those interfaces and probably generate those methods – user May 25 '20 at 16:36

1 Answers1

1

You can add external method extension via implicit class

object ValueImplicits {

  implicit class ValueOps(val value: Value) extends AnyVal {
    def +(v: Value): Value = value.add(v)
  }

}

Now it can work like this

import ValueImplicits._

val v1 = new Value {}
val v2 = new Value {}
val v3 = v1 + v2

You can avoid the import if you can create a companion object for interface Value in the same package.

object Value {

  implicit class ValueOps(val value: Value) extends AnyVal {
    def +(v: Value): Value = value.add(v)
  }

}

Implicit resolution checks companion objects without any explicit import.

Ivan Stanislavciuc
  • 7,140
  • 15
  • 18
  • 2
    Companion is not just an object with same name as class/trait and in the same package. It must be in the same scope and in the same file. Otherwise it's just an object with same name but not companion. So nobody can create companion object for Java interface. – Dmytro Mitin May 25 '20 at 16:24