15

I'm writing a DSL where the "+" operator is strictly numeric, like some other popular languages. It's close, but the String "+" operator is messing up my implicit conversions. What's the syntax for unimporting an operator of the String class?

Just to be clearer, instead of this:

scala> var x = "2" + 3;
x: java.lang.String = 23

I'd like to get x: Int = 5

I imagine I just need 2 things to make that happen:

  • Remove (unimport within my scope) the definition of "+" from Strings
  • Define an implicit conversion of String to Int

I'm stuck on the first step.

Thanks

Alex R
  • 11,364
  • 15
  • 100
  • 180
  • 3
    I suppose that "import scala.Predef.{any2stringadd => _}" would work. But it doesn't. There must be something I missed. – Eastsun Apr 19 '10 at 04:26
  • 4
    `any2stringadd` is used where the left hand side doesn't support the `+` operator, but the right hand side is a string. (To see this in action, run `scala -Xprint:typer` and execute `new Object + "ZZZZZ"`) By contrast, `"ZZZZZ" + new Object` can use the + operator that's already defined on `String`, so `any2stringadd` is not used. – Ken Bloom Apr 19 '10 at 14:17

3 Answers3

9

According to section 12.3.1 of the Scala spec, the + method for String has special treatment by the compiler. I don't know for sure, but I think this means you can't "unimport" it, which is a shame because it really breaks the type system (much like the related toString method).

Could you use a different name for the operator in your DSL, eg, ++ or &?

Kristian Domagala
  • 3,686
  • 20
  • 22
  • 2
    The fact that the `+` method get special treatment by the compiler has nothing to do with whether it can be imported or unimported. The language is supposed to be very orthagonal, and treat all class methods semantically the same, regardless of whether they're syntheized by the compiler or provided by the runtime library. – Ken Bloom Apr 19 '10 at 14:11
  • I would agree with what you are saying if `+` were indeed explicitly specified on the `String` class, but the specification only alludes to this, and IMO could be interpreted as saying that there is an implicit conversion (that is baked into the compiler and hence can't be "unimported") to some type (eg, `StringAdd`), which allows clients to treat `String` as if it were defined with a `+` method. I'm happy to be proven wrong here, but even through runtime reflection on `String` (and `RichString`), I can't find a `+` (ie `$plus`) method. – Kristian Domagala Apr 21 '10 at 05:34
  • 2
    Thanks, sounds like another case of "compiler magic" which actually breaks orthogonality and has unexpected interactions with other language features and libraries. – Alex R Apr 23 '10 at 04:00
  • Yes, I'm not sure why it couldn't be implemented in the same way as `Predef.any2stringadd`, eg `Predef.string2stringadd:String => StringAdd`. – Kristian Domagala Apr 23 '10 at 04:19
  • In modern scala, it's possible to unimport String and use a custom interpolator to produce a custom type. What's not currently possible is supplying a custom "empty" interpolator for string literal syntax. – som-snytt Jan 10 '20 at 22:15
4

The + method for a string is a method on of the String class (and therefore on each string object), and as such it cannot be unimported.

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
1

You can't unimport it, but you could use +: and define it on the int class. What would be best is if you write it like this: "2".toInt + 3.

Anonymous
  • 821
  • 1
  • 5
  • 14