Question

The lift code:

import net.liftweb.util.Helpers._

object test extends App {

  val xml = <div>
    <span name="a">a</span>
    <span name="b">b</span>
  </div>

  val t1 = if (true) {
    "@a" #> "xxx"
  } else {
    "@a" #> "yyy"
  } &
    "@b" #> "zzz"

  val t2 = (if (true) {
    "@a" #> "xxx"
  } else {
    "@a" #> "yyy"
  }) &
    "@b" #> "zzz"

  println("------------- t1 ------------")
  println(t1(xml))

  println("------------- t2 ------------")
  println(t2(xml))

}

The output:

------------- t1 ------------
<div>
    xxx
    <span name="b">b</span>
  </div>
------------- t2 ------------
<div>
    xxx
    zzz
  </div>

Strange, right? The only difference is that the t2 has wrapped if else with ().

My friend decompiled the bytecode and found that scala has compiled the t1 similar to:

t1 = true ? "@a" #> "xxx" : "@a" #> "yyy" & "@b" #> "zzz"

As if the code is:

 if (true) 
    "@a" #> "xxx"
  else 
    "@a" #> "yyy" &
    "@b" #> "zzz"

Where is wrong?

Was it helpful?

Solution

I guess it has to do with the operator precedence and the way code is parsed. To get a very precise answer one would have to look closely at Scala's spec.

In general, I would recommend to write a function for @a and another for @b to make things really clear when reading code. E.g.:

def ta = 
  if (true) "@a" #> "xxx"
  else "@a" #> "yyy"

def tb = "@b" #> "zzz"

val t1 = ta & tb

Scala has a very lightweight syntax that encourages such definition unlike many other programming language. Your code tend to be much more readable when using it. Have a look at Odersky's talk on Scala with Style. He explains other interesting tricks too.

OTHER TIPS

Nothing is wrong. { } around a single statement doesn't make any changes to the code. Remember, the result of a block is the result of the last statement, so if you have just one, you can also omit the { }. But even if you had multiple statements, the & is binding first, see as an example

if (false) {true; 1} else {false; 3} & {true; 2}

The result is 2 (the result of 3&2).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top