Accessing variable from enclosing scope at runtime - scala

I am working to implement a DSL that will - among other things - allow me to wrap a block of code in a context. For simplicity, the context in this example is just a string.
The code block wrapped by that context could contain anything, but will also contain calls to func1. Now, within func1 I would like to have access to the ID of the enclosing context.
def func1() = {
// Would like to access the context ID here
// i.e. "MY_CONTEXT"
}
def func2()(implicit x: String) = {
// Can access x here, but that would be "OTHER".
}
def context(id: String)(body: => Unit) = {
// How can body make use of id ?
body
}
implicit val c = "OTHER"
context("MY_CONTEXT") {
func1()
func2()
}
I have looked into using an implicit parameter. This can be seen with func2. However, it seems that this would need to be declared just above the call to context. This defeats the purpose, as I only want to specify it with the context call.
I hope the example code is enough to illustrate the problem. Any suggestion on how to keep the context(id)(body) construct as shown and be able to access the context ID within func1? Your help is much appreciated.

Related

Why is it allowed to put methods inside blocks, and statements inside objects in Scala?

I'm learning Scala and I don't really understand the following example :
object Test extends App {
def method1 = println("method 1")
val x = {
def method2 = "method 2" // method inside a block
"this is " + method2
}
method1 // statement inside an object
println(x) // same
}
I mean, it feels inconsistent to me because here I see two different concepts :
Objects/Classes/Traits, which contains members.
Blocks, which contains statements, the last statement being the value of the block.
But here we have a method part of a block, and statements part of an object. So, does it mean that blocks are objects too ? And how are handled the statements part of an object, are they members too ?
Thanks.
Does it mean that blocks are objects too?
No, blocks are not objects. Blocks are used for scoping the binding of variables. Scala enables not only defining expressions inside blocks but also to define methods. If we take your example and compile it, we can see what the compiler does:
object Test extends Object {
def method1(): Unit = scala.Predef.println("method 1");
private[this] val x: String = _;
<stable> <accessor> def x(): String = Test.this.x;
final <static> private[this] def method2$1(): String = "method 2";
def <init>(): tests.Test.type = {
Test.super.<init>();
Test.this.x = {
"this is ".+(Test.this.method2$1())
};
Test.this.method1();
scala.Predef.println(Test.this.x());
()
}
}
What the compiler did is extract method2 to an "unnamed" method on method2$1 and scoped it to private[this] which is scoped to the current instance of the type.
And how are handled the statements part of an object, are they members
too?
The compiler took method1 and println and calls them inside the constructor when the type is initialized. So you can see val x and the rest of the method calls are invoked at construction time.
method2 is actually not a method. It is a local function. Scala allows you to create named functions inside local scopes for organizing your code into functions without polluting the namespace.
It is most often used to define local tail-recursive helper functions. Often, when making a function tail-recursive, you need to add an additional parameter to carry the "state" on the call stack, but this additional parameter is a private internal implementation detail and shouldn't be exposed to clients. In languages without local functions, you would make this a private helper alongside the primary method, but then it would still be within the namespace of the class and callable by all other methods of the class, when it is really only useful for that particular method. So, in Scala, you can instead define it locally inside the method:
// non tail-recursive
def length[A](ls: List[A]) = ls match {
case Nil => 0
case x :: xs => length(xs) + 1
}
//transformation to tail-recursive, Java-style:
def length[A](ls: List[A]) = lengthRec(ls, 0)
private def lengthRec[A](ls: List[A], len: Int) = ls match {
case Nil => len
case x :: xs => lengthRec(xs, len + 1)
}
//tail-recursive, Scala-style:
def length[A](ls: List[A]) = {
//note: lengthRec is nested and thus can access `ls`, there is no need to pass it
def lengthRec(len: Int) = ls match {
case Nil => len
case x :: xs => lengthRec(xs, len + 1)
}
lengthRec(ls, 0)
}
Now you might say, well I see the value in defining local functions inside methods, but what's the value in being able to define local functions in blocks? Scala tries to as simple as possible and have as few corner cases as possible. If you can define local functions inside methods, and local functions inside local functions … then why not simplify that rule and just say that local functions behave just like local fields, you can simply define them in any block scope. Then you don't need different scope rules for local fields and local functions, and you have simplified the language.
The other thing you mentioned, being able to execute code in the bode of a template, that's actually the primary constructor (so to speak … it's technically more like an initializer). Remember: the primary constructor's signature is defined with parentheses after the class name … but where would you put the code for the constructor then? Well, you put it in the body of the class!

Anonymous functions with parameters

When you see code that follows this pattern:
def index = Action { request =>
// ..
}
Action trait: https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L65
When looking at this code, how would you know that the request object is available to use within the code block? (is there a intellij shortcut for this?)
Can someone please create a miniature example of where you can mimic this pattern so I can understand how this works, and if you can explain in technical terms what is going on?
The Action trait is not of interest here. Instead, because the body of the index method must be a value, not a type, you are looking at the Action object. You can learn more about objects here. Let's first simplify the syntax by removing syntactic sugar, i.e. making the program behave the same but with simpler constructs. If you try to call an object as if it were a method, what really happens is that .apply is inserted for you by the compiler:
def index = Action.apply((request) => {
// ..
})
This may be more familiar; the apply method is being called on the Action object, passing a lambda function that takes a request. And obviously, an argument to a lambda is always available within that lambda. That's the point of them.
The lambda in this case is also known as a callback. A simple example that clarifies these features follows:
object WithAnswer {
def apply(f: Int => Unit): Unit =
f(42)
}
def printAnswer() = WithAnswer { answer =>
println(answer)
}
This is called as Loan pattern
withWriter creates a writer for the user and then ensures the resource (writer) is properly closely after using.
All that user has to do is just use the writer and write something to the file
def withWriter(file: File)(f: Writer => Unit): Unit = {
val writer = new PrintWriter(file)
try {
f(writer)
} finally {
writer close
}
}
Usage:
withWriter(new File("some_fix.txt") { writer =>
writer println("write something")
}

debugging scala futures - how to determine the future's execution context

related with another question I posted (scala futures - keeping track of request context when threadId is irrelevant)
when debugging a future, the call stack isn't very informative (as the call context is usually in another thread and another time).
this is especially problematic when there can be different paths leading to the same future code (for instance usage of DAO called from many places in the code etc).
do you know of an elegant solution for this?
I was thinking of passing a token/request ID (for flows started by a web server request) - but this would require passing it around - and also won't include any of the state which you can see in the stack trace.
perhaps passing a stack around? :)
Suppose you make a class
case class Context(requestId: Int, /* other things you need to pass around */)
There are two basic ways to send it around implicitly:
1) Add an implicit Context parameter to any function that requires it:
def processInAnotherThread(/* explicit arguments */)(
implicit evaluationContext: scala.concurrent.EvaluationContext,
context: Context): Future[Result] = ???
def processRequest = {
/* ... */
implicit val context: Context = Context(getRequestId, /* ... */)
processInAnotherThread(/* explicit parameters */)
}
The drawback is that every function that needs to access Context must have this parameter and it litters the function signatures quite a bit.
2) Put it into a DynamicVariable:
// Context companion object
object Context {
val context: DynamicVariable[Context] =
new DynamicVariable[Context](Context(0, /* ... */))
}
def processInAnotherThread(/* explicit arguments */)(
implicit evaluationContext: scala.concurrent.EvaluationContext
): Future[Result] = {
// get requestId from context
Context.context.value.requestId
/* ... */
}
def processRequest = {
/* ... */
Context.context.withValue(Context(getRequestId, /* ... */)) {
processInAnotherThread(/* explicit parameters */)
}
}
The drawbacks are that
it's not immediately clear deep inside the processing that there is some context available and what contents it has and also referential transparency is broken. I believe it's better to strictly limit the number of available DynamicVariables, preferably don't have more than 1 or at most 2 and document their use.
context must either have default values or nulls for all its contents, or it must itself be a null by default (new DynamicVariable[Context](null)). Forgetting to initialize Context or its contents before processing may lead to nasty errors.
DynamicVariable is still much better than some global variable and doesn't influence the signatures of the functions that don't use it directly in any way.
In both cases you may update the contents of an existing Context with a copy method of a case class. For example:
def deepInProcessing(/* ... */): Future[Result] =
Context.context.withValue(
Context.context.value.copy(someParameter = newParameterValue)
) {
processFurther(/* ... */)
}

What does the word "Action" do in a Scala function definition using the Play framework?

I am developing Play application and I've just started with Scala. I see that there is this word Action after the equals sign in the function below and before curly brace.
def index = Action {
Ok(views.html.index("Hi there"))
}
What does this code do? I've seen it used with def index = { but not with the word before the curly brace.
I would assume that the name of the function is index. But I do not know what the word Action does in this situation.
This word is a part of Play Framework, and it's an object, which has method apply(block: ⇒ Result), so your code is actually:
def index: Action[AnyContent] = Action.apply({
Ok.apply(views.html.index("Hi there"))
})
Your index method returns an instance of the class Action[AnyContent].
By the way, you're passing a block of code {Ok(...)} to apply method, which (block of code) is actually acts as anonymous function here, because the required type for apply's input is not just Result but ⇒ Result, which means that it takes an anonymous function with no input parameters, which returns Result. So, your Ok-block will be executed when container, received your instance of class Action (from index method), decided to execute this block. Which simply means that you're just describing an action here - not executing - it will be actually executed when Play received your request - and find binding to your action inside routing file.
Also, you don't have to use def here as you always return same action - val or lazy val is usually enough. You will need a def only if you actually want to pass some parameter from routing table (for instance):
GET /clients/:id controllers.SomeController.index(id: Long)
def index(id: Long) = Action { ... } // new action generated for every new request here
Another possible approach is to choose Action, based on parameter:
def index(id: Long) = {
if (id == 0) Action {...} else Action{...}
}
But uasually you can use routing table itself for that, which is better for decoupling. This example just shows that Action is nothing more than return value.
Update for #Kazuya
val method1 = Action{...} //could be def too, no big difference here
// this (code inside Action) gonna be called separately after "index" (if method2 is requested of course)
// notice that it needs the whole request, so it (request) should be completely parsed at the time
val method2 = Action{ req => // you can extract additional params from request
val param1 = req.headers("header1")
...
}
//This is gonna be called first, notice that Play doesn't need the whole request body here, so it might not even be parsed on this stage
def index(methodName: String) = methodName match {
case "method1" => method1
case "method2" => method2
}
GWT/Scala.js use simillar approach for client-server interaction. This is just one possible solution to explain importance of the parameter "methodName" passed from routing table. So, action could be thought as a wrapper over function that in its turn represents a reference to OOP-method, which makes it useful for both REST and RPC purposes.
The other answers deal with your specific case. You asked about the general case, however, so I'll attempt to answer from that perspective.
First off, def is used to define a method, not a function (better to learn that difference now). But, you're right, index is the name of that method.
Now, unlike other languages you might be familiar with (e.g., C, Java), Scala lets you define methods with an expression (as suggested by the use of the assignment operator syntax, =). That is, everything after the = is an expression that will be evaluated to a value each time the method is invoked.
So, whereas in Java you have to say:
public int three() { return 3; }
In Scala, you can just say:
def three = 3
Of course, the expression is usually more complicated (as in your case). It could be a block of code, like you're more used to seeing, in which case the value is that of the last expression in the block:
def three = {
val a = 1
val b = 2
a + b
}
Or it might involve a method invocation on some other object:
def three = Numbers.add(1, 2)
The latter is, in fact, exactly what's going on in your specific example, although it requires a bit more explanation to understand why. There are two bits of magic involved:
If an object has an apply method, then you can treat the object as if it were a function. You can say, for example, Add(1, 2) when you really mean Add.apply(1,2) (assuming there's an Add object with an apply method, of course). And just to be clear, it doesn't have to be an object defined with the object keyword. Any object with a suitable apply method will do.
If a method has a single by-name parameter (e.g., def ifWaterBoiling(fn: => Tea)), then you can invoke the method like ifWaterBoiling { makeTea }. The code in that block is evaluated lazily (and may not be evaluated at all). This would be equivalent to writing ifWaterBoiling({ makeTea }). The { makeTea } part just defines an expression that gets passed in, unevaluated, for the fn parameter.
Its the Action being called on with an expression block as argument. (The apply method is used under the hood).
Action.apply({
Ok("Hello world")
})
A simple example (from here) is as follows (look at comments in code):
case class Logging[A](action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Result = {// apply method which is called on expression
Logger.info("Calling action")
action(request) // action being called on further with the request provided to Logging Action
}
lazy val parser = action.parser
}
Now you can use it to wrap any other action value:
def index = Logging { // Expression argument starts
Action { // Action argument (goes under request)
Ok("Hello World")
}
}
Also, the case you mentioned for def index = { is actually returning Unit like: def index: Unit = {.

Scala Implicit parameters by passing a function as argument To feel the adnvatage

I try to feel the advantage of implicit parameters in Scala. (EDITED: special case when anonymous function is used. Please look at the links in this question)
I try to make simple emulation based on this post. Where explained how Action works in PlayFramework. This also related to that.
The following code is for that purpose:
object ImplicitArguments extends App {
implicit val intValue = 1 // this is exiting value to be passed implicitly to everyone who might use it
def fun(block: Int=>String): String = { // we do not use _implicit_ here !
block(2) // ?? how to avoid passing '2' but make use of that would be passed implicitly ?
}
// here we use _implicit_ keyword to make it know that the value should be passed !
val result = fun{ implicit intValue => { // this is my 'block'
intValue.toString // (which is anonymous function)
}
}
println(result) // prints 2
}
I want to get "1" printed.
How to avoid passing magic "2" but use "1" that was defined implicitly?
Also see the case where we do not use implicit in definition, but it is there, because of anonymous function passing with implicit.
EDITED:
Just in case, I'm posting another example - simple emulation of how Play' Action works:
object ImplicitArguments extends App {
case class Request(msg:String)
implicit val request = Request("my request")
case class Result(msg:String)
case class Action(result:Result)
object Action {
def apply(block:Request => Result):Action = {
val result = block(...) // what should be here ??
new Action(result)
}
}
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}
println(action)
}
Implicits don't work like this. There is no magic. They are just (usually) hidden parameters and are therefore resolved when invoking the function.
There are two ways to make your code work.
you can fix the implicit value for all invocations of fun
def fun(block: Int=>String): String = {
block(implicitly[Int])
}
implicitly is a function defined in Predef. Again no magic. Here's it's definition
def implicitly[A](implicit value: A) = value
But this means it will resolve the implicit value when declaring the fun and not for each invocation.
If you want to use different values for different invocations you will need to add the implicit paramter
def fun(block: Int=>String)(implicit value: Int): String = {
block(value)
}
This will now depend on the implicit scope at the call site. And you can easily override it like this
val result = fun{ _.toString }(3)
and result will be "3" because of the explicit 3 at the end. There is, however, no way to magically change the fun from your declaration to fetch values from implicit scope.
I hope you understand implicits better now, they can be a bit tricky to wrap your head around at first.
It seems that for that particular case I asked, the answer might be like this:
That this is not really a good idea to use implicit intValue or implicit request along with implicitly() using only one parameter for the function that accept (anonymous) function.
Why not, because:
Say, if in block(...) in apply() I would use implicitly[Request], then
it does not matter whether I use "implicit request" or not - it will use
request that is defined implicitly somewhere. Even if I would pass my
own request to Action { myOwnRequest =Result }.
For that particular case is better to use currying and two arguments and.. in the second argument - (first)(second) to use implicit
Like this:
def apply(block:Request => Result)(implicit request:Request):Action2
See my little effort around this example/use case here.
But, I don't see any good example so far in regards to how to use implicit by passing the (anonymous) function as argument (my initial question):
fun{ implicit intValue => {intValue.toString}
or that one (updated version):
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}