What does "()" stand for in: val f = {() => x += 1} - scala

My question is about Scala function:
var x = 1
val f = {() => x += 1}
It's clear if the function literal looks like:
val f = (x:Int)=>x+1
But what does () stand for in:
val f = {() => x += 1}
I am pretty new in Scala.
I've read out the function chapter in a Scala book already, but still cannot understand what () means here.

tl;dr It's just an empty argument list of a function.
It's an empty argument list. It means you're not passing any arguments to the function. So normally that kind of function would not consume any value, but would supply value when it's called.
Your case is special. Variable x comes from the outer scope and is bound to your function so it becomes closure. Every time you invoke f it will change the value of x.

The () in the val f = {() => x += 1} represents the function takes no argument and increase value of x by 1
it is similar to
var x = 1
def foo(): Unit = {
x += 1
}
val f: () => Unit = () => x += 1
This is not a pure function

f is of type () => Unit. A function that takes no arguments and returs nothing (Unit)
val f: () => Unit = {() => x += 1}
The java equivalent of this would be the Supplier interface.

Related

scala: How to convert an anonymous function to val

I'm a beginner learning scala and looking into anon functions and vals.
I'm not able to convert {case e if e % 2 == 0 => e} to a Val. I've tried different syntax (sample shown below) to no avail. There is no real purpose for converting to val; just trying to get a deeper understanding.
package exercises.functions
object CollectVal extends App {
println(List(1,2,3,4,5).collect{case e if e % 2 == 0 => e})
// val onlyEvens: Int = e:Int => Int = e if (e % 2 == 0 ) => e
// val onlyEvens = e:Int = {case e if e % 2 == 0 => e}
println(List(1,2,3,4,5).collect{onlyEvens})
}
Any help is appreciated
Thanks!
What you need to express is a function. So the type of the variable in this case is:
val onlyEvens: Int => Int
In particular, collect accept a PartialFunction (i.e. a function that is not defined for some input value). So it is more correct to write:
val onlyEvens: PartialFunction[Int, Int] = { case e if e % 2 == 0 => e }
Finally, you can pass this val in the collect method:
List(1,2,3,4,5).collect(onlyEvens)
Scastie
Syntax to assign an anonymous function to a val would be something like this (note parentheses around e):
val x: Int => Int = (e) => if (e % 2 == 0) e else ???
or equivalently, but a bit shorter: val x = (e: Int) => if (e % 2 == 0) e else ???
But it looks like what you are looking for is a partial function rather than just a function. PartialFunction is like a regular function, but it is only defined for some of the possible values of its parameter. In your case, you want it only defined for even numbers:
val x = PartialFunction[Int, Int] { case e if e % 2 == 0 => e }
The { case foo => bar } shorthand works for partial functions but not regular functions, that's why you were having problems trying to define a function that way. This creates a PartialFunction that is defined for all integer values that match one of the case clauses, and not for any others.

Scala function definition vs application

Why does f in the following code snippet gives the value of 1. I was expected f() to be 1. How can I obtain a reference to the function f:()=> Int
var y = 0
def f():Int = {y + 1}
f
Somethings in scala drive me nuts.
If you're calling a function that has no parameters, then you can drop the brackets. That's why f evaluates to 1.
The exact same expression can also evaluate into a function reference if the compiler knows that you're expecting a value of that type.
val foo: () => Int = f
You can obtain so using _ :
var y = 0
def m:Int = {y + 1}
val result = m _ // type of result is an instance of Function0 "() => Int"
Use _ when compiler is not expecting Function object.
If you want f to be an expression of type () => Int that evaluates to { y + 1 }, then just define it as such:
var y = 0
val f: () => Int = () => { y + 1 }
Now
f
does nothing (it just gives back the lambda of type () => Int), but
f()
gives 1.
You don't really need the type ascription, this works too:
val f = () => { y + 1 }

Passing a function to another function as statement

I want to write a function which will return true if given an even number as an argument or false otherwise. additionally, write a function that will filter a list of numbers returning just the even numbers. All done using Scala functional programming. This is what I have:
def isEven(n:Int): Boolean = n % 2 == 0
println(isEven(4))
val filterEven = ( xs :List[Int] ) => {
for( x <- xs; if x % 2 == 0 ) yield x
}
println(filterEven(List(3,2,4,5,6,22,91)))
My question is, how can I pass the first function "isEven" to to the "filterEven" function in order to replace the "if-statement"?
Regards.
You can pass isEven as a parameter to xs.filter
def filterEven(xs: List[Int]) = xs.filter(isEven)
This is functionally equivalent to:
def filterEven(xs: List[Int]) = for { x <- xs if isEven(x) } yield x
First you give it a name when it is passed in.
val filterEven = (xs :List[Int], filterFunc: Int => Boolean) => {
Then you invoke it under its new name.
for(x <- xs; if filterFunc(x)) yield x
Note that now filterEven is not a good name for your function. The parameter passed in as filterFunc will determine whether you filter even, or odd, or less than 100, or .....

val x = { println("hello") } as inline function

I execute the following assignment:-
val x = { println("hello") }
This prints hello and also prints the type of x as:-
x: Unit = ()
My understanding was that an inline function has been created and assigned to val x. So with that assumption I tried executing x as:-
x
It doesn't error out. But also prints nothing. Isn't that a function which x is holding?
What this line does:
val x = { println("hello") }
is this: it executes println("hello") and then assigns what println returns to the value x. Since println returns Unit, x will be assigned Unit.
The correct syntax for what you want to do (assign a function to x) is this:
val x = () => { println("hello") }
You can then call the function with:
x()
(which is short-hand syntax for x.apply()).
You are not assigning a function to x, you are assigning the result of a block to x. The block is executed immediately and the result (Unit) is assigned to x.
The result of a block is the result of the last statement in the block, and the result of println() is Unit.
val x = () => { println("hello") }
will assign a function to x, which can be called like this:
x()
Alternatively you can use def instead of val. val introduces constant values defined as the result of the block defining them. In your example, println("hello") is executed, then its returning value is named x. On the contrary, def introduces a method whose body is executed every time you call it.
def x = println("hello")
will then be executed every time x is called. But even with def, it's still not a function. To make it a function you have two options:
you can define directly a function (x1 : T1, ..., xn : Tn) => expr where x1 to xn are the arguments of the function, Ti is the type of xi and expr is the code you want to execute (which depends on parameters x1 to xn and anything in scope).
scala> val x = () => println("hello")
x: () => Unit = <function0>
or you can define a method as before and use the syntax methodName _ to transform your method into a function :
scala> def x = println("hello")
x: Unit
scala> x _
res0: () => Unit = <function0>

How to invoke no-arg anonymous function with no parentheses

Take this code:
var x = 10
val y = () => x + 1
I then want to treat y as if its a variable that holds an Int and changes anytime x changes. Essentially I want to bind y to x.
Problem is, if I just type y then I get the result res0: () => Int = <function0>
I was under the impression that you could invoke 0-arity functions without any parens, but I am required to use y() to get the behavior I am trying to achieve.
Is there a better way to define the anonymous function or do I need to use a different approach?
Why do you need to do it like that? Just do def y = x + 1
scala> var x = 1
x: Int = 1
scala> def y = x + 1
y: Int
scala> y
res0: Int = 2
scala> x = 3
x: Int = 3
scala> y
res1: Int = 4
EDIT to address some comments:
If you define val y = () => x + 1, you are defining y as a value that holds a function that takes no argument and returns an Int. To call the function that is held by this variable, you will need to call it with (), to tell the compiler that you don't want to pass the value, but to execute (evaluate) the function that is within it.
If you define val y = x + 1, you are defining a value (constant), that is assigned in the moment it is executed, you could postpone evaluation using lazy, but once it is assigned, it will not be evaluated again.
If you define def y = x + 1, you are defining a function that returns x+1, which is what you want.
You have not defined a 0-arity function. You have actually defined a Unit => Int function. That is why you can not invoke it like you would like to invoke it. I've rarely seen 0-arity functions outside the context of come contained function scope:
def something[V](value: Int)(f: => V) =
if(value %2 == 0) f
else throw new Exception("not even (and also not evaluated f)")
where it is used as a lazily deferred execution body.
Edit: I would use the other person's answer.