Warnings while executing a function in a function - scala

I created one function:
def ignore(f: Unit => Unit) = {
userDisabled = true
f
userDisabled = false
}
Now I get a warning:
a pure expression does nothing in statement position; you may be omitting necessary parentheses
When I add the parentheses, and write f(), I get:
Adaptation of argument list by inserting () has been deprecated: this is unlikely to be what you want. signature: Function1.apply(v1: T1): R given arguments: after adaptation: Function1((): Unit)
What am I doing wrong?

You probably wanted to declare ignore as
def ignore(f: () => Unit) = {
userDisabled = true
f()
userDisabled = false
}
With is function with 0 arity that returns Unit
Currently you have a 1 arg function that expects parameter of type Unit. There is only one value with such type and it is ().
When you simply say f, you do nothing, you don't call the function, hence the first warning. It is as if you just put:
userEnabled = true
42
userEnabled = false
When you say f() you are not passing an argument to a function that expects one. Scala can put there Unit for you, but it is deprecated, hence the second warning. You should call it as f(()).
Another option could be call by name parameter
def ignore(f: => Unit) = {
userDisabled = true
f
userDisabled = false
}
in that case f would cause side effects to happen each time you use it in the method body. This is the most common way of doing such thing as from caller perspective you can just say
ignore {
//code
}
instead of
ignore(() => {
//code
})

Writing a function without parenthesis, f, is an indication that it has no side effects, that the function is "pure". Since your function call without parens isn't the last statement, it would not be returned, and thus has no overall effect.
When you right this f() you're writing that your function takes no arguments. But it really does! It takes something of type Unit. Before Scala used to infer this for you but due to several issues you must now, since 2.11, provide it manually as f(())

Related

How to handle tail recursion with futures

Consider the following example
def futureFoo() = {
Future.successful(true)
}
def recFoo(x: List[Int]): Unit = {
if (x.isEmpty) return
for {
b <- futureFoo()
v = getNewListOfValues(x.last)
_ = recFoo(v)
} yield b
}
I need to wait for futureFoo to finish and only then call recFoo again. The problem is no matter what I try I get the following error:
discarded non-Unit value
I also tried to convert it into a while loop but because of the future I either get the same error or the while condition doesn't update because it must be updated in a for comprehension or map.
Any ideas on how to prevent that error?
Try this.
def recFoo(x: List[Int]): Unit =
if (x.nonEmpty)
futureFoo().foreach(_ => recFoo(getNewListOfValues(x.last)))
The specific reason that you are getting
discarded non-Unit value
in your error message is that you have an expression after return.
Note that in Scala, the return keyword should almost never be used. Scala is an expression-oriented language; each block (such as a function body) evaluates to the value returned from the last line in the block.
So, for example, consider the following snippet:
val foo = {
import scala.util.Random
if (Random.nextInt() % 2 == 0) {
17
} else {
"bar"
}
}
Everything from if to the closing brace after "bar" is a single expression -- NOT a statement. Scala, in fact, does not have "if-statements" in the way that Java and other languages do. In particular, the compiler needs to infer a type for the name foo, and since foo could concretely be either the Int 17 or the String "bar", that inferred type is the closest common ancestor of both Int and String, which is Any.
In your question, the last expression in the body of recFoo is the following:
for {
b <- futureFoo()
v = getNewListOfValues(x.last)
_ = recFoo(v)
} yield b
What is the type of this expression? In many languages, for introduces a statement, but that's not true of Scala -- this is an expression, not a statement, and like all expressions it will have a value once we evaluate it. That value has type Future[Unit], and like all non-Unit values, the compiler is warning you that you are discarding a value, which is (almost) always a mistake. (Why would you go to the trouble of producing a non-Unit value and then not make use of it?, goes the thinking.)

Scala : match case syntax vs => S?

def phrase[T](p: Parser[T]) = new Parser[T] {
def apply(in: Input) = lastNoSuccessVar.withValue(None) {
p(in) match {
case s # Success(out, in1) =>
if (in1.atEnd)
s
else
lastNoSuccessVar.value filterNot { _.next.pos < in1.pos } getOrElse Failure("end of input expected", in1)
case ns => lastNoSuccessVar.value.getOrElse(ns)
}
}
}
The function above is found in Scala's source code.
What confuses me is : withValue's declaration is
def withValue[S](newval: T)(thunk: => S): S
then,
what is the meaning of => S ?
and what is the relationship with match case syntax ?
The meaning of => S is anything that can give a S, either a literal or a function without parameter.
As parameter definition, a parameter by-name, it allows to not compute the S value when calling, but 'inside' withValue (and only when required). A kind of lazy val equivalent for parameter.
def foo: String = someComputation
withValue("literal")
withValue(foo)
// foo not called before passing to withValue
The type => S of the parameter thunk means that thunk is a call-by-name parameter.
Normally, when you pass an argument to a method, the argument is evaluated immediately before the method is called. With a call-by-name parameter, it is not evaluated when the method is called, but only when the method uses the argument.
This can be useful for expressions that have side effects or that are expensive to evaluate - you can avoid evaluating them at all if the method doesn't need the result of evaluating the argument.
In your example, the whole block { p(in) match { ... } } is what's passed for the parameter thunk to the method withValue. The method withValue will evaluate the block only when necessary, instead of that the block is evaluated before withValue is called.
This has no direct relation with match.
There are three separate issues:
passing function as parameter
def withValue[S](newval: T)(thunk: => S): S
thunk is function that transform whatever to S.
Easier example:
def withValue[S](newval: T)(thunk: Long => S): S
thunk is function that transform Long to S.
type classes
S type is determined when you pass thunk function to you method. Type classes are used to determine releations betwen types in method/class
http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html
match clause
p(in) just return Success or Failure that can be matched by match/case
http://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html

In Scala invoking no-parameter function with and without brackets is executed in different way

I have following Currying function declaration:
def logString(count: Int)(fun:() => Unit) {
for (n <- 1 to count) { fun }
}
I call this function in this way:
logString(3) { () => print("I") }
The result is nothing - just no output.
Then I just add brackets after "fun" function invocation, inside the body of Currying function declaration:
def logString(count: Int)(fun:() => Unit) {
for (n <- 1 to count) { fun() }
}
The result becomes what is expected:
III
Is this some Scala bug, or there is some rule that I missed when learning Scala?
I know that there is rule that when you declare function like this:
def myFun = 1
we can not invoke it with brackets - the compilation fails.
But having different results when invoking a function with and without brackets seems more like a bug.
Am I right or I miss something about Scala?
Look at the type of fun, it's fun: () => Unit. You can think of that as meaning that when you call it with (), you get Unit in return. Without explicitly calling it, fun refers to the function as a value, not the result of calling it. This is the essence of the concept of higher-order functions.
If it had type fun: => Unit, simply mentioning fun would cause it to be executed, in which case there would be no way to refer the function as a value.
When you have such a declaration
val x = 10
this is a value definition. The value x can be an integer like in this case,
but it can also be a function.
val y = () => println("i'm a function")
However either way, if you call it without parenthesis nothing will happen.
scala> val x = 10
x: Int = 10
scala> val y = () => println("i'm a function")
y: () => Unit = <function0>
scala> x
res0: Int = 10
scala> y
res1: () => Unit = <function0>
When you have a function definition like this:
def z() = println("i'm a function def")
Then you can omit parenthisis and call it without it.
scala> def z() = println("i'm a function def")
z: ()Unit
scala> z
i'm a function def
In your case fun is like a value definition (it's a value parameter).
What happens is that, when Scala evaluates your for expression it will just do nothing with fun.
Just the same as if you did y vs y() from the example above.
I just wanted to share the information summarized by me based on the very helpful answers answers above and some additional research. Might be would be helpful for someone else also.
Functions can be declared in two ways in Scala:
- "call-by-name" - they are represented in the byte code as normal Java functions in a straightforward way.
- "call-by-value" - from Scala's abstract point of view they are stored in variables. Actually in the Byte code they are stored in classes implementing Single Abstract Method interfaces (SAM) and passed around as method parameters or as normal variables.
When we invoke a "call-by-name" function that does not take parameters it is always executed no matter how we call it with or without brackets.
So now myFunction and myFunction() is just the same.
When we invoke a "call-by-value" function that does not take parameters we have two cases:
- when we do not have brackets after it - myFunction - we just refer to the variable pointing to the function without executing function itself.
- when we have brackets - myFunction() - we actually call (execute) the function.
Different ways to declare function:
def myFunction = 5 * 5
This is call-by-name function. Declared this way no brackets allowed when calling it. So calling myFunction() will not compile. Call it this way: myFunction
def myFunction() = 5 * 5
This is call-by-name function. Can call the function with and without brackets - the effect is the same. So myFunction and myFunction() is just the same.
def myFunction = () => 5 * 5
This is call-by-value function (even when declared as def not val) . When calling it with brackets - myFunction() - function is executed, when calling it without brackets - myFunction - function is NOT executed - just val holding it is being mentioned.
Similarly if we declare function as other function's parameter:
def enclosingFunc(myFunction: => Void)
This is call-by-name function. Inside enclosing function it will be executed only if called without brackets - myFunction. With brackets - myFunction() - will not compile.
In this case enclosingFunc could be called this way:
enclosingFunc(n = 1; n +=1)
def enclosingFunc(myFunction: () => Int)
This is call-by-value function. It matters how we invoke it in the body of enclosing function. If invoke it without brackets - myFunction - it will NOT be executed, but we just refer to the object holing it. If invoke it with brackets - myFunction() - it will be called and executed.
In this case enclosingFunc could be called only in this way:
enclosingFunc( () => n = 1; n +=1)
In the first example the function fun doesn't isn't invoked, it juts sort of sits there. Adding the parenthesis cause the passed-in function to be evaluated.

Scala no argument string function vs typed String parameter

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"
})

Scala Returning a void function with 0 parameters, ugly syntax?

Given a method defined as follows
def descendEach(times:Int)(f:()=>Unit) {
for (i <- 1 to times) {
// other code
f()
}
}
when I use this method I want to be able to write
gd.descendEach(20){
println(gd.cost)
}
but the scala compiler only lets me get away with
gd.descendEach(20){ () =>
println(gd.cost)
}
which is kind of ugly. Am I missing something here? Is it possible to write it in the first way I presented?
Use the following syntax:
def descendEach[T](times:Int)(f: => T)
This way you can not only pass function without extra () => (this is called pass by name), but also use functions returning any type (not necessarily Unit). It is sometimes convenient when you have an existing function you want to pass but don't really care about its return value:
def g() = 42
descendEach(20)(g)
Note that with this syntax you are simply using f, not f().