I have a Future of Tuple like this Future[(WriteResult, MyObject)] mytuplefuture, I'd like to map it and do something with MyObject so I am doing this:
mytuplefuture.map((wr,obj)=>{ //do sth});
but my eclipse scala IDE does not allow and recommend me to do:
mytuplefuture.map{ case(wr,obj) => { //do sth }}
what is the difference between those two?
I am used to doing the first one, I do not know about the second one until I try returning that tuple that wrapped in a future
myfuture.map((obj) => { // do sth with obj })
it was clear, I am mapping the content of the Future and do something with it, which will return another future because the original myfuture only contains something (obj) in the future..
Would anyone explain please?
The difference is this:
map is a higher-order function (HOF) that takes a function as its argument. This function - let's call it the mapping function for convenience - itself takes a single argument, which is the value of the completed Future. In this particular case, this value happens to be a tuple. Your first attempt assumed that the tuple could be broken open into two arguments, which would then be accepted by the mapping function - but that's not going to happen, hence the error.
It might seem that you could define the mapping function like this (note the extra parentheses around the arguments):
mytuplefuture.map(((wr,obj)) => /* do sth */)
however this is not currently supported by the Scala compiler. (That said, I think this might be a feature of a future Scala release.)
So, the alternative is to write the mapping function as a partial function using the case statement. The following:
mytuplefuture.map {
case (wr,obj) => //
}
is actually a kind of shorthand for:
mytuplefuture.map {
tuple: (WriteResult, MyObject) => tuple match {
case (wr,obj) => // do sth
}
}
In fact, this shorthand is generally useful for situations other than just breaking open tuples. For instance:
myList.filter {
case A => true
case _ => false
}
is short for:
myList.filter {
x => x match {
case A => true
case _ => false
}
}
So, let's say you wish to look at just the MyObject member of the tuple. You would define this as follows:
val myfuture = mytuplefuture.map {
case (_, obj) => obj
}
or, alternatively, being explicit with the tuple argument:
val myfuture = mytuplefuture.map(tuple => tuple._2)
which can in turn be simplified to just:
val myfuture = mytuplefuture.map(_._2)
where the first underscore is shorthand for the first argument to the mapping function. (The second underscore, as in _2, is part of the name for the second value in the tuple, and is not shorthand - this is where Scala can get a little confusing.)
All of the previous three examples return a Future[MyObject].
If you then apply map to this value, the single mapping function argument in this case will be your MyObject instance. Hence you can now write:
myfuture.map(obj => /* Do something with obj */)
As to the remainder of your question, the mapping function as applied to a Future's value does indeed apply to the result of the original future, since it can't be executed until the first future has completed. Therefore, map returns a future that completes (successfully or otherwise) when the first future completes.
UPDATED: Clarified what the argument to map actually is. Thanks to #AlexeyRomanov for putting me right, and to #RhysBradbury for pointing out my initial error. ;-)
The difference is, that case indicates decomposition (or extraction) of the object (invoking unapply, which you can implement yourself).
myfuture.map(obj => obj._2 ) in this case obj - is your tuple, so you can access its elements by ._1 and ._2
mytuplefuture.map{ case(wr,obj) => { //do sth }} this decompose tuple to its elements.
You can better feel the difference, by using this approach on case class which comes with a default unapply implementation
case class MyClass(int: Int)
List(MyClass(1)) map { myclass => myclass.int } // accesing the elements
List(MyClass(1)) map { case MyClass(i) => i + 1 } // decomposition
In your case I'd write
mytuplefuture.map(_.2).map( // do somthing )
P.S.
You can do the extraction for many other classes (Option for example).
It is also allowing you to write something like
val (a, b) = tuple
val MyClass(x) = myclass
Related
What is still unclear for is what's the advantage by-name parameters over anonymous functions in terms of lazy evaluation and other benefits if any:
def func1(a: => Int)
def func2(a: () => Int)
When should I use the first and when the second one?
This is not the copy of What's the difference between => , ()=>, and Unit=>
Laziness is the same in the both cases, but there are slight differences. Consider:
def generateInt(): Int = { ... }
def byFunc(a: () => Int) { ... }
def byName(a: => Int) { ... }
// you can pass method without
// generating additional anonymous function
byFunc(generateInt)
// but both of the below are the same
// i.e. additional anonymous function is generated
byName(generateInt)
byName(() => generateInt())
Functions with call-by-name however is useful for making DSLs. For instance:
def measured(block: ⇒ Unit): Long = {
val startTime = System.currentTimeMillis()
block
System.currentTimeMillis() - startTime
}
Long timeTaken = measured {
// any code here you like to measure
// written just as there were no "measured" around
}
def func1(a: => Int) {
val b = a // b is of type Int, and it`s value is the result of evaluation of a
}
def func2(a: () => Int) {
val b = a // b is of type Function0 (is a reference to function a)
}
An example might give a pretty thorough tour of the differences.
Consider that you wanted to write your own version of the veritable while loop in Scala. I know, I know... using while in Scala? But this isn't about functional programming, this is an example that demonstrates the topic well. So hang with me. We'll call our own version whyle. Furthermore, we want to implement it without using Scala's builtin while. To pull that off we can make our whyle construct recursive. Also, we'll add the #tailrec annotation to make sure that our implementation can be used as a real-world substitute for the built-in while. Here's a first go at it:
#scala.annotation.tailrec
def whyle(predicate: () => Boolean)(block: () => Unit): Unit = {
if (predicate()) {
block()
whyle(predicate)(block)
}
}
Let's see how this works. We can pass in parameterized code blocks to whyle. The first is the predicate parameterized function. The second is the block parameterized function. How would we use this?
What we want is for our end user to use the whyle just like you would the while control structure:
// Using the vanilla 'while'
var i = 0
while(i < args.length) {
println(args(i))
i += 1
}
But since our code blocks are parameterized, the end-user of our whyle loop must add some ugly syntactic sugar to get it to work:
// Ouch, our whyle is hideous
var i = 0
whyle( () => i < args.length) { () =>
println(args(i))
i += 1
}
So. It appears that if we want the end-user to be able to call our whyle loop in a more familiar, native looking style, we'll need to use parameterless functions. But then we have a really big problem. As soon as you use parameterless functions, you can no longer have your cake and eat it too. You can only eat your cake. Behold:
#scala.annotation.tailrec
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
if (predicate) {
block
whyle(predicate)(block) // !!! THIS DOESN'T WORK LIKE YOU THINK !!!
}
}
Wow. Now the user can call our whyle loop the way they expect... but our implementation doesn't make any sense. You have no way of both calling a parameterless function and passing the function itself around as a value. You can only call it. That's what I mean by only eating your cake. You can't have it, too. And therefore our recursive implementation now goes out the window. It only works with the parameterized functions which is unfortunately pretty ugly.
We might be tempted at this point to cheat. We could rewrite our whyle loop to use Scala's built-in while:
def whyle(pred: => Boolean)(block: => Unit): Unit = while(pred)(block)
Now we can use our whyle exactly like while, because we only needed to be able to eat our cake... we didn't need to have it, too.
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
But we cheated! Actually, here's a way to have our very own tail-optimized version of the while loop:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal(predicate2: () => Boolean)(block2: () => Unit): Unit = {
if (predicate2()) {
block2()
whyle_internal(predicate2)(block2)
}
}
whyle_internal(predicate _)(block _)
}
Can you figure out what we just did?? We have our original (but ugly) parameterized functions in the inner function here. We have it wrapped with a function that takes as arguments parameterless functions. It then calls the inner function and converts the parameterless functions into parameterized functions (by turning them into partially applied functions).
Let's try it out and see if it works:
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
And it does!
Thankfully, since in Scala we have closures we can clean this up big time:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal: Unit = {
if (predicate) {
block
whyle_internal
}
}
whyle_internal
}
Cool. Anyways, those are some really big differences between parameterless and parameterized functions. I hope this gives you some ideas!
The two formats are used interchangeably, but there are some cases where we can use only one of theme.
let's explain by example, suppose that we need to define a case class with two parameters :
{
.
.
.
type Action = () => Unit;
case class WorkItem(time : Int, action : Action);
.
.
.
}
as we can see, the second parametre of the WorkItem class has a type Action.
if we try to replace this parameter with the other format =>,
case class WorkItem1(time : Int, s : => Unit) the compiler will show a message error :
Multiple markers at this line:
`val' parameters may not be call-by-name Call-by-name parameter
creation: () ⇒
so as we have see the format ()=> is more generic and we can use it to define Type, as class field or method parameter, in the other side => format can used as method parameter but not as class field.
A by-name type, in which the empty parameter list, (), is left out, is only
allowed for parameters. There is no such thing as a by-name variable or a
by-name field.
You should use the first function definition if you want to pass as the argument an Int by name.
Use the second definition if you want the argument to be a parameterless function returning an Int.
Okay, I guess question is already complete in the title.
Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:
def doMyStuff(): Future[_] = {
val result = db.queryMyData().map {
case some(data) =>
val modifiedData = data.doStuff()
modifiedData
case None =>
Errors.THIS_IS_FALSE
}
result
}
Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.
Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.
The code which uses that is for example something like this:
doMyStuff().map {
case data: MyDataType => // Blah blah
case Errors.Value => // error handling
}
So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?
It is a matter of semantics:
The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.
T[Any] means there has to be a subclass Any present.
The difference comes into play when you want to serialize the underlying class.
If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.
I ran across a function that looks like this:
def doSomethingQuestionable(config: someConfig, value: String)(default: => String) : String
What is interesting is the parameterless function that gets passed in as second argument group. In the code base, the method is only ever called with a config and two strings, the latter being some default value, but as a String, not a function. Within the code body of the method, default is passed on to a method that takes 3 string arguments. So the function "default" only resolves down to a string within the body of this method.
Is there any benefit, apart from a currying usage which does not happen with this method in the code base I am going through, of defining the method this way? Why not just define it with 3 string arguments in a single argument group?
What am I missing? Some compiler advantage here? Keep in mind, I am assuming that no currying will ever be done with this, since it is a large code base, and it is not currently done with this method.
The point is to have a potentially expensive default string that is only created when you need it. You write the code as if you're creating the string to pass in, but because it's a by-name parameter ('=> String') it will actually be turned into a function that will be transparently called whenever default is referenced in the doSomethingQuestionable method.
The reason to keep it separate is in case you do want a big block of code to create that string. If you never do and never will, it may as well be
def doSomethingQuestionable(config: someConfig, value: String, default: => String): String
If you do, however,
def doSomethingQuestionable(cfg, v){
// Oh boy, something went wrong
// First we need to check if we have a database accessible
...
// (Much pain ensues)
result
}
is way better than embedding the code block as one argument in a multi-argument parameter list.
This is a parameterless function returning a String:
() => String
Which is not what you have. This,
=> <WHATEVER>
is a parameter being passed by-name instead of by-value. For example:
=> String // A string being passed by-name
=> () => String // A parameterless function returning string being passed by-name
The difference between these modes is that, on by-value, the parameter is evaluated and the resulting value is passed, whereas on by-name, the parameter is passed "as is", and evaluated each time it is used.
For example:
var x = 0
def printValue(y: Int) = println(s"I got $y. Repeating: $y.")
def printName(y: => Int) = println(s"I got $y. Repeating: $y.")
printValue { x += 1; x } // I got 1. Repeating: 1.
printName { x += 1; x } // I got 2. Repeating: 3.
Now, as to why the method splits that into a second parameter, it's just a matter of syntactic pleasantness. Take the method foldLeft, for example, which is similarly defined. You can write something like this:
(1 to 10).foldLeft(0) { (acc, x) =>
println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}")
acc+x
}
If foldLeft was defined as a single parameter list, it would look like this:
(1 to 10).foldLeft(0, { (acc, x) =>
println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}")
acc+x
})
Not much different, granted, but worse looking. I mean, you don't write this thing below, do you?
if (x == y, {
println("Same thing")
}, {
println("Different thing"
})
Just like Stream is a lazy Seq, is there a lazy version of Map?
What I want to do:
val lm = LazyMap[Int, String]((a) => {
println("only once")
(a * a).toString()
})
lm.get(10) // print "only once"
lm.get(10) // print nothing
You are basically asking for a cache.
You might have a shot at using scalaz.Memo, which adds memoization to a given function.
See http://eed3si9n.com/learning-scalaz/Memo.html
This would give something like:
val lm: Int => String = Memo.mutableHashMapMemo[Int, String] { a =>
println("only once")
(a * a).toString()
}
Note however that what you get is a function, not a map. This means that you cannot test for the presence or absence of a given key, you can only apply.
But if I am to trust your example, in your case this is exactly what you want.
mutable.Map provides the method getOrElseUpdate(key: A, op: ⇒ B): B. You could use that to implement lazy semantics.
You should wrap the class in another class though, because else the value can be changed later by anyone who has the reference to that map.
I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(not sure how it is related to the loan pattern)
Edit Little explanation as requested in comment.
Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.
First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention.
If you write
val inc = {i: Int => i + 1}
it is desugared to
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(defines an anonymous class extending Function1, with given apply method and creating an instance)
So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.
On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.
A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.
What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.
Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.