Using curly braces for code blocks

#1

From time to time I’d like to use {} around code blocks so I can, for example,
define local variables only visible inside the block. As I understand, this is syntax supported by the compiler. See the comments // block 1 and // block 2 below.

The problem is that If I put the comments in the code, the compiler complains

Error:(410, 11) Long does not take parameters
          {

And if I remove the comment, IntelliJ, tries to re-align the open brace at the end of the previous line.
Is there a syntax I can use which both the compiler and IntelliJ will be happy about?

// This function prints statistics about which version of quineMccluskeyReduce is faster,
// i.e., version1 or version 2
 def stressTest():Unit = {
    var v1 = 0
    var v2 = 0
    (8 to 25).foreach { numVars =>
      println(s"   numVars=$numVars")
      (numVars / 2 to numVars).foreach { density => {
        (numVars * numVars * 2 to numVars * numVars * 3).foreach { numClauses =>
          val cnf = genCNF(numVars, numClauses, density)
          val t0:Long = System.nanoTime()
            // block 1
          {
            val vec = QmVec(cnf)
            quineMccluskeyReduce(vec,1)
          }
          val t1:Long = System.nanoTime()
            // block 2
          {
            val vec = QmVec(cnf)
            quineMccluskeyReduce(vec,2)
          }
          val t2:Long = System.nanoTime()
          if ((t1 - t0) > (t2 - t1))
          // v2 faster than v1
            v2 += 1
          else
          // v1 faster than v2
            v1 += 1
        }
      }
        println(s"time version 1=$v1  time version 2=$v2   v1/v2=${(v1 + 1.0) / v2}")
      }
    }
  }
#2

The problem here is the semicolon inference. The compiler and also Intellij think, that the block belongs to the previous line, which contains a Long, hence the error “Long does not take parameters”.

You can manually add a ; to the line before the block (i.e. val t1:Long = System.nanoTime();), which will fix the compiler error, but for me IntelliJ still formats wrong but different: the braces and everything in them are indented one level to the left from where they should be. I’d say it’s better than putting the brace on the previous line, but still not perfect.

1 Like
#3

is there some sort of no-op block keyword I can use? I suppose I could write a simply function which evaluates its call-by-name argument…


val t0:Long = System.nanoTime();

block{
  val vec = QmVec(cnf)
  quineMccluskeyReduce(vec,1)
}
#4

I’d probably recommend a different function name, just to avoid confusion – blocking in that context has a very specific meaning, having to do with thread management…

#5

In your concrete example, why not a function that actually does the timing?

def time[T](block: => T): (T, Long) = {
  val start = System.nanoTime()
  (block, System.nanoTime() - start)
}

Then:

val (_, td1) = time {
  val vec = QmVec(cnf)
  quineMccluskeyReduce(vec,1)
}
val (_, td2) = time {
  val vec = QmVec(cnf)
  quineMccluskeyReduce(vec,2)
}
if (td1 > td2)
  v2 += 1
else
  v1 += 1
#6

@sangamon, yes of course there are ways around the problem. For example, I don’t really need the braces at all. The question was just how to make the compiler and the editor support this language feature consistently.

I wasn’t trying to make production worthy code, I was just trying to test to implementations of a function to see if one or the other merited deleting.

#7

you could use locally from Predef, which is an alias for identity (so, does nothing), and its name somewhat fits your purpose (having some variables in a local scope only).

Edit: it looks like locally was added for exactly that purpose

2 Likes
#8

Isn’t the behavior of the compiler against the specification? My reading of the spec is that it should terminate these statements.

#9

There is an exception for opening curly braces in there, see the last list in that section:

A single new line token is accepted

  • in front of an opening brace ‘{’, if that brace is a legal continuation of the current statement or expression,

That is the reason the comments break compilation, probably, as an empty line betweeen the opening brace and the line before should work (see second example in the spec).