I'm trying to get into Scala by trying to use Scalatra. I finished Martin Odersky course on coursera some time ago but I still have a hard time understaning how this works:
package com.example.app
import org.scalatra._
class HelloWorldApp extends ScalatraFilter {
get("/") {
<h1>Hello, {params("name")}</h1>
}
}
This example is taken from Scalatra main page: http://www.scalatra.org/
How this statement is executed:
get("/") { Hello, {params("name")} }
Is {}
a parameter of get()
method?
Can you explain what features of Scala language are in use here? Pointers at Scalatra source code would be perfect defining this would be perfect.
get
is defined in CoreDsl as follows
def get(transformers: RouteTransformer*)(block: => Any): Route
So, get
takes two parameters, a sequence of route transformers (strings are implicitly converted into route transformers) and a parameterless method that outputs something of type Any
. The interesting part here is this second parameter.
The first thing to understand is that parameterless methods as function arguments are handled specially in Scala, namely as call-by-name, see Automatic Type-Dependent Closure Construction and also Scala Language Reference, Section 6.6, p. 78, which is p. 86 of the PDF:
The case of a formal parameter with a parameterless method type
=> T
is treated specially. In this case, the corresponding actual argument expressione
is not evaluated before the application. Instead, every use of the formal parameter on the right-hand side of the rewrite rule entails a re-evaluation ofe
. In other words, the evaluation order for=>
-parameters is call-by-name whereas the evaluation order for normal parameters is call-by-value.
The second aspect is that in function application, arguments can be enclosed either in ()
(the "regular" arguments) or {}
(more precisely, in this case they must be block expressions, and they can even start on a new line), see Scala Language Reference on Function Application, Section 6.6 on p. 77, which is p. 85 of the PDF.
Note also how these two features are a significant part of what makes Scala an attractive language for defining DSLs (or new keyword-like features).
Parts of the following question might also be interesting What's the difference between multiple parameters lists and multiple parameters per list in Scala?
Is {} a parameter of get() method?
Yes. get
will have two parameter lists. One is for the path "\"
and the other for the block to execute. Blocks are enclosed in {}
, parameters in ()
. So you would seem to have to call it as
class HelloWorldApp extends ScalatraFilter {
get("/") ({
<h1>Hello, {params("name")}</h1>
})
}
but there's some syntactic sugar that allows a single parameter in {}
to be passed without having to add the ()
. You see this more commonly in things like
myList foreach { do_something() }
It's a very useful feature for writing what look like, and are used like, new control structures but are actually just functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With