Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Odersky serious with "bills !*&^%~ code!"?

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?

like image 250
stacker Avatar asked Apr 27 '10 21:04

stacker


4 Answers

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.

like image 174
Daniel C. Sobral Avatar answered Nov 12 '22 01:11

Daniel C. Sobral


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.

like image 37
scaling_out Avatar answered Nov 11 '22 23:11

scaling_out


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.

like image 34
Wysawyg Avatar answered Nov 11 '22 23:11

Wysawyg


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.

like image 2
Jesper Avatar answered Nov 11 '22 23:11

Jesper