views:

387

answers:

5

In his book programming in scala (Chapter 5 Section 5.9 Pg 93) Odersky mentioned this expression "bills !*&^%~ code!"

In the footnote on same page:

"By now you should be able to figure out that given this code,the Scala compiler would

invoke (bills.!*&^%~(code)).!()."

That's a bit to cryptic for me, could someone explain what's going on here?

+2  A: 

I'm not sure if the book provides method signatures but I assume it's just a comment on Scala's syntactic sugar so it assumes if you type:

bill add monkey

where there is an object bill which has a method add which takes a parameter then it automatically interprets it as:

bill.add(monkey)

Being a little Scala rusty, I'm not entirely sure how it splits code! into (code).!() except for a vague tickling of the grey cells that the ! operator is used to fire off an actor which in compiler terms might be interpretted as an implicit .!() method on the object.

Wysawyg
stacker
+2  A: 

The period is optional for calling a method that takes a single parameter, or has an empty parameter list.

When this feature is utilized, the next chunk after the space following the method name is assumed to be the single parameter.

Therefore,

(bills.!*&^%~(code)).!().

is identical to

bills !*&^%~ code!

The second exclamation mark calls a method on the returned value from the first method call.

scaling_out
stacker
Jesper
+4  A: 

I for one think that Mr. Odersky should avoid the confusing multitude of symbols and write the profanity out in ASCII. At least, that's what I'd f✻❀king do.

Ricky Clarkson
+7  A: 

What Odersky means to say is that it would be possible to have valid code looking like that. For instance, the code below:

class BadCode(whose: String, source: String) {
  def ! = println(whose+", what the hell do you mean by '"+source+"'???")
}

class Programmer(who: String) {
  def !*&^%~(source: String) = new BadCode(who, source)
}

val bills = new Programmer("Bill")
val code = "def !*&^%~(source: String) = new BadCode(who, source)"
bills !*&^%~ code!

Just copy&paste it on the REPL.

Daniel
@Daniel thank you so much for this amazing example. You should be awarded a scala balck belt badge.
stacker
@stacker I've got a gold badge, it should suffice for now. :-)
Daniel
+1  A: 

The combination of the '.()' being optional with method calls (as Wysawyg explained above) and the ability to use (almost) whatever characters you like for naming methods, makes it possible to write methods in Scala that look like operator overloading. You can even invent your own operators.

For example, I have a program that deals with 3D computer graphics. I have my own class Vector for representing a 3D vector:

class Vector(val x: Double, val y: Double, val z: Double) {
    def +(v: Vector) = new Vector(x + v.x, y + v.y, z + v.z)

    // ...etc.
}

I've also defined a method ** (not shown above) to compute the cross product of two vectors. It's very convenient that you can create your own operators like that in Scala, not many other programming languages have this flexibility.

Jesper

related questions