While reading Play! Framework documentation, I came across this snippet:
def index = Action { implicit request =>
session.get("connected").map { user =>
Ok("Hello " + user)
}.getOrElse {
Unauthorized("Oops, you are not connected")
}
}
Documentation explains implicit
there:
Alternatively you can retrieve the Session implicitly from a request
Besides, I read this post: Literal with Implicit and it seems logically that function cannot have implicit parameter.
If I well figured out, this is because a function, contrary to method has always a contract (interface).
Indeed, for instance, Function1[Int, Function1[Int, Int]]
has as a return type's first parameter an Int
, and thus prevents us to annotate this one as implicit
. This would lead to a confusion about its high-level return type: () => Int
or Int => Int
...
Therefore, what the previous snippet code behaves with implicit since first Action
's required parameter is a literal function.
I guess the reason allowing compiler to accept this code is the multiple signatures of Action.apply()
method:
def apply(block: Request[AnyContent] => Result): Action[AnyContent]
def apply(block: => Result): Action[AnyContent]
(redirecting to the first one)
Since the second doesn't need some parameter, is this one selected in presence of a literal function's implicit parameter?
Consider the following code:
If this function:
is in scope, then the first code snippet will compile, because clearly the implicit parameter
myImplicitClass
will be passed to the functionsession
in order to access the fieldmyImplicitClass.session
, allowing you to omit the field access. This is exactly the trick the Play! Framework is using, checkController
to find thesession
function.As a side note, the above closure is not stating that it takes an implicit parameter, it's a language feature to avoid having to do the following:
when one wants to use a closure parameter as an implicit value in the body of the closure. Also note that as of Scala 2.9, you are limited to closures with exactly 1 parameter for this trick.