scope and benefit of implicit parameter request in a scala play action? - scala

I can understand how use implicit parameters but I've the doubt about how necessary is it for the scala play actions...in the play documentation appear this:
It is often useful to mark the request parameter as implicit so it can be implicitely used by other APIs that need it
now...reading this other stackoverflow answer:
Implicit keyword before a parameter in anonymous function in Scala
seems than the use the implicit parameter here is only a "syntax sugar" for
Action { request =>
Ok("Got request [" + request + "]",request) //with implicit request I avoid pass the request parameter...
}
my question are:
1) is the scope from the implicit parameter only the scope from my lambda no?...
2) do I'm ignoring something about it?...
reading this other answer:
When should I make methods with implicit argument in Scala?
seems than use implicit parameter in this case is "overuse"
3) How would look a code without use implicit parameter and what boilerplate I'm avoiding using it??
I rewrite this code https://stackoverflow.com/a/5015161/340451 without implicit parameter and definitions and the code was much more readable and clear (less implicit :D)...I know useful cases where implicit parameters are really helpful (example: the akka api) but I can't understand how useful is it pattern and why must be used...
thanks!

1) Yes, the scope of the request is within the action block
2) Sorry, don't understand this question
In general you should use implicits sparingly. We think the use of an implicit to pass around the request is reasonable in this particular context.

Related

What is the best way to avoid clashing between two typeclass definitions in shapeless

Shapeless has a neat type class derivation mechanism that allows you to define typeclasses and get automatic derivation for any typeclass.
To use the derivation mechanism as a user of a typeclass, you would use the following syntax
import MyTypeClass.auto._
which as far as I understand it is equivalent to
import MyTypeClass.auto.derive
An issue arises when you try and use multiple typeclasses like such within the same scope. It would appear that the Scala compiler only considers the last definition of derive even though there are two versions of the function "overloaded" on their implicit arguments.
There are a couple ways I can think of to fix this. Instead of listing them here, I will mark them as answers that you can vote on to confirm sanity as well as propose any better solution.
I raised this question back in April and proposed two solutions: defining the method yourself (as you suggest):
object AutoCodecJson {
implicit def deriveEnc[T] = macro deriveProductInstance[EncodeJson, T]
implicit def deriveDec[T] = macro deriveProductInstance[DecodeJson, T]
}
Or using aliasing imports:
import AutoEncodeJson.auto.{ derive => deriveEnc }
import AutoDecodeJson.auto.{ derive => deriveDec }
I'd strongly suggest going with aliasing imports—Miles himself said "hadn't anticipated that macro being reused that way: not sure I approve" about the deriveProductInstance approach.
Instead of inheriting from the Companion trait, define the auto object and apply method yourself within your companion object and name them distinctively. A possible drawback to this is that two separate librairies using shapeless could end up defining a derive method with the same name and the user would end up again with a situation where he cannot use the derivation process for both type classes within the same scope in his project.
Another possible drawback is that by dealing with the macro call yourself, you may be more sensitive to shapeless API changes.
Modify/fix the Scala compiler to accept two different methods overloaded on their implicit parameters.
Is there any reason why this is impossible in theory?

How do scala implicit values work?

This is not a question about implicit in general - I know how it works. It's about one specific construct. Here comes a quite common patten in myBatis for Scala:
manager.readOnly { implicit session => {
//Code block: Do some DB operations in session
}
}
Definition of readOnly can be found here: https://github.com/mybatis/scala/blob/master/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/SessionManager.scala
How I read it: Call a readOnly method on manager with its argument being a function that takes session as an argument.
My question is: Where implicit session value is taken from? Which context? I do not have to define any session object by myself.
Implicit parameters provide a way to allow parameters of a method to be "found". This means that if a parameter value is not supplied then the compiler will search for an "implicit" value defined within scope according to resolution rules:
Variable has to be marked implicit to be considered as a candidate
Explicit definitions override implicits
Local scope is looked first
Classes companion object is searched if it exists
Scala documentation puts it this way:
First, eligible are all identifiers x that can be accessed at the
point of the method call without a prefix and that denote an implicit
definition or an implicit parameter. Second, eligible are also all
members of companion modules of the implicit parameter’s type that are
labeled implicit.
It seems there's also a bunch of edge cases and not a whole lot of good documentation so I don't encourage to go crazy with implicits or you might be in for a surprise.
My question is: Where implicit session value is taken from? Which
context? I do not have to define any session object by myself.
In this example, implicit session is a formal parameter declaration for the function literal it begins. Thus the actual value is supplied by the code in readOnly that will invoke that function in carrying out its operation.
Making it implicit here means the code in the function body (which I presume to be a Slick query) wants / needs / prefers an implicit parameter for the sake of notational convenience. (Implicit formal parameters may always have their actual parameter passed explicitly).
Incidentally, the inner braces are unnecessary and should be omitted.

When should I make methods with implicit argument in Scala?

I made codes using play framework in scala which look like the following:
object Application extends Controller {
def hoge = Action( implicit request =>
val username = MyCookie.getName.get
Ok("hello " + username)
}
}
object MyCookie {
def getName( implicit request: RequestHeader ) = {
request.cookies.get("name").map(_.value)
}
}
I got a code review from my coworker. He said this code is not readable because of implicit parameter. I couldn't reply to his opinion. So could you tell me what is the best way to use implicit parameters? When should I use implicit parameters?
You should use implicit parameters when there is almost always a "right" way to do things, and you want to ignore those details almost all the time; or when there often is no way to do things, and the implicits provide the functionality for those things that work.
For an example of the first case, in scala.concurrent.Future, almost every method takes an implicit ExecutionContext. You almost never care what your ExecutionContext is from call to call; you just want it to work. But when you need to change the execution context you can supply it as an explicit parameter.
For an example of the second case, look at the CanBuildFroms in the collections library. You cannot build anything from anything; certain capabilities are supplied, and the lack of an implicit that, say, lets you package up a bunch of Vector[Option[String]]s into a HashSet[Char] is one major way to keep the library powerful and flexible yet sane.
You are doing neither: apparently you're just using it to save a little typing in one spot at the expense of the other spot. And, in this case, in doing so you've made it less obvious how things work, as you have to look all over the place to figure out where that implicit request actually gets used. If you want to save typing, you're much better off using short variable names but being explicit about it:
Action{ req => val name = MyCookie.getName(req).get; Ok("hello "+name) }

Collision of implicits in Scala

The following Scala code works correctly:
val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)
However if I import the implicit method
implicit def stringToNode(str: String): xml.Node = new xml.Text(str)
then the Scala (2.10) compiler shows an error: value zip is not a member of String
It seems that the presence of stringToNode somehow blocks the implicit conversion of str1 and str2 to WrappedString. Why? And is there a way to modify stringToNode such that zip works but stringToNode is still used when I call a function that requires a Node argument with a String?
You have ambiguous implicits here. Both StringOps and xml.Node have the zip-method, therefore the implicit conversion is ambiguous and cannot be resolved. I don't know why it doesn't give a better error message.
Here are some links to back it up:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps
and
http://www.scala-lang.org/api/current/index.html#scala.xml.Node
edit: it was StringOps, not WrappedString, changed the links :) Have a look at Predef: http://www.scala-lang.org/api/current/index.html#scala.Predef$
to see predefined implicits in Scala.
I would avoid using implicits in this case. You want 2 different implicit conversions which both provide a method of the same name (zip). I don't think this is possible. Also, if you import xml.Text, you can convert with just Text(str) which should be concise enough for anyone. If you must have this implicit conversion to xml.Node, I would pack the implicit def into an object and then import it only in the places where you need it to make your code readable and to, possibly, avoid conflicts where you also need to zip strings. But basically, I would very much avoid using implicits just to make convenient conversions.
Like #Felix wrote, it is generally a bad idea to define implicit conversions between similar data types, like the one you used. Doing that weakens type system, leads to ambiguities like you encountered and may produce extremely unclear ("magic") code which is very hard to analyze and debug.
Implicit conversions in Scala are mostly used to define lightweight, short-lived wrappers in order to enrich API of wrapped type. Implicit conversion that converts String into WrappedString falls into that category.
Twitter's Effective Scala has a section about this issue.

How does Scala's apply() method magic work?

In Scala, if I define a method called apply in a class or a top-level object, that method will be called whenever I append a pair a parentheses to an instance of that class, and put the appropriate arguments for apply() in between them. For example:
class Foo(x: Int) {
def apply(y: Int) = {
x*x + y*y
}
}
val f = new Foo(3)
f(4) // returns 25
So basically, object(args) is just syntactic sugar for object.apply(args).
How does Scala do this conversion?
Is there a globally defined implicit conversion going on here, similar to the implicit type conversions in the Predef object (but different in kind)? Or is it some deeper magic? I ask because it seems like Scala strongly favors consistent application of a smaller set of rules, rather than many rules with many exceptions. This initially seems like an exception to me.
I don't think there's anything deeper going on than what you have originally said: it's just syntactic sugar whereby the compiler converts f(a) into f.apply(a) as a special syntax case.
This might seem like a specific rule, but only a few of these (for example, with update) allows for DSL-like constructs and libraries.
It is actually the other way around, an object or class with an apply method is the normal case and a function is way to construct implicitly an object of the same name with an apply method. Actually every function you define is an subobject of the Functionn trait (n is the number of arguments).
Refer to section 6.6:Function Applications of the Scala Language Specification for more information of the topic.
I ask because it seems like Scala strongly favors consistent application of a smaller set of rules, rather than many rules with many exceptions.
Yes. And this rule belongs to this smaller set.