Manu Chadha
Manu Chadha

Reputation: 16755

unable to understand syntax of Action method in Play

How could I pass a block of code (instead of parenthesis) to Action? I am unable to understand this syntax. Shouldn't I use ()

val echo = Action { request =>
  Ok("Got request [" + request + "]")
} 

I suppose Action is Function1. The following example from Scala, uses (), so how Action works with {}

object Main extends App {
   val succ = (x: Int) => x + 1 //create Function 1
   val anonfun1 = new Function1[Int, Int] { //create another Function1
     def apply(x: Int): Int = x + 1
   }
   assert(succ(0) == anonfun1(0)) //notice use of ()
}

I later tested using () instead of {} and the code still works. So is the use of {} to only improve readability?

val echo = Action ( request =>
  Ok("Got request [" + request + "]")
) 

Upvotes: 2

Views: 98

Answers (2)

sarveshseri
sarveshseri

Reputation: 13985

Looks like you need to read more about Scala.

Lets first begin with basics,

scala> val a = 5
// a: Int = 5

Here, the RHS is just 5 and is called a expression eiteral or a literal expression.

Similarly, Scala also allows,

scala> val a = { 5 }
// a: Int = 5

Here, the RHS is { 5 } and is called a block expression and this block here evaluates to 5.

Now, let move on to a our use case

scala> object A {
     |   def apply(i: Int) = i + 5
     | }
// defined module A

Now, Scala allows us to use this A in two ways,

val x1 = A(10)
// x1: Int = 15

// Or
val x2 = A { 10 }
// x2: Int = 15

Why ? Take a look at Scala Language Specification - Functional Application

Here, you will see following grammer,

SimpleExpr    ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs ::=  ‘(’ [Exprs] ‘)’
                |  ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
                |  [nl] BlockExpr
Exprs         ::=  Expr {‘,’ Expr}

So, if we use ( and ) to apply a function then we can provide any Expr (even multiple) otherwise we have to provide a BlockExpr

Now, lets talk about your example (simplified for explanation),

val echo = Action( request => Ok("") )

// VS

val echo = Action { request => Ok("") }

The difference exist in how it gets parsed by the parser.

The parsing for first one proceeds with the following rules,

SimpleExpr        ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs     ::=  ‘(’ [Exprs] ‘)’
Exprs             ::=  Expr {‘,’ Expr}
Expr              ::=  (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr

Where second one uses the following rules,

SimpleExpr        ::=  SimpleExpr1 ArgumentExprs
ArgumentExprs     ::=  [nl] BlockExpr
BlockExpr         ::=  ‘{’ Block ‘}’
Block             ::=  BlockStat {semi BlockStat} [ResultExpr]
ResultExpr        ::=  (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Block             ::=  BlockStat {semi BlockStat} [ResultExpr]
BlockStat         ::=  Expr1

Full parse-tree expressions,

enter image description here

Upvotes: 4

shayan
shayan

Reputation: 1241

In Scala parentheses and curly braces are interchangeable in various scenarios one of them being the wrapper () in a function`s argument list.

def multiply(num: Int)(by: Int): Int = num * by

multiply(5)(2)
multiply{5}{2}

the curly braces syntax also allows for multi line expressions to be written inside:

multiply{
  val num = 5
  num
}{
  val by = 2
  by
}

Upvotes: 1

Related Questions