开发者

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

开发者 https://www.devze.com 2022-12-28 15:24 出处:网络
In his book programming in scala (Chapter 5 S开发者_运维问答ection 5.9 Pg 93) Odersky mentioned this expression \"bills !*&^%~ code!\"

In his book programming in scala (Chapter 5 S开发者_运维问答ection 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?


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号