Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala's infix notation with object +, why not possible?

Tags:

scala

I can name objects like this, but can't call m:

object + {
  def m (s: String) = println(s)
}

Can't call +.m("hi"):

<console>:1: error: illegal start of simple expression
       +.m("hi")

Also can't call + m "hi" (preferred for DSL-usage).

But with object ++ it works fine! Do they conflict with (not existent) unary_+ methods? Is it possible to avoid this?

like image 398
Themerius Avatar asked Nov 13 '12 19:11

Themerius


3 Answers

Indeed it is not possible with unary operators. If you want to call it anyways, you could resort to using the name generated by the compiler for the JVM (which starts with a dollar):

scala> object + {
     | def m( s: String ) = println(s)
     | }
defined module $plus

scala> +.m("hello")
<console>:1: error: illegal start of simple expression
       +.m("hello")
        ^

scala> $plus.m("hello")
hello
like image 99
paradigmatic Avatar answered Nov 07 '22 15:11

paradigmatic


I believe the problem is that in order to handle unary operators without ambiguity, scala relies on a special case: only !, +, - and ~ are treated as unary operators. Thus in +.m("hi"), scala treat + as an unary operator and can't make sense of the whole expression.

like image 6
Régis Jean-Gilles Avatar answered Nov 07 '22 14:11

Régis Jean-Gilles


Another code using package:

object Operator extends App {
    // http://stackoverflow.com/questions/13367122/scalas-infix-notation-with-object-why-not-possible
    pkg1.Sample.f
    pkg2.Sample.f
}

package pkg1 {
    object + {
        def m (s: String) = println(s)
    }

    object Sample {
        def f = {
            // +.m("hi") => compile error: illegal start of simple expression
            // + m "hi" => compile error: expected but string literal found.
            $plus.m("hi pkg1")
            $plus m "hi pkg1"
        }
    }
}

package pkg2 {
    object + {
        def m (s: String) = println(s)
    }

    object Sample {
        def f = {
            pkg2.+.m("hi pkg2")
            pkg2.+ m "hi pkg2"
            pkg2.$plus.m("hi pkg2")
            pkg2.$plus m "hi pkg2"
        }
    }
}

java version "1.7.0_09"

Scala code runner version 2.9.2

like image 1
J Camphor Avatar answered Nov 07 '22 15:11

J Camphor