Scala function definition vs application - scala

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 }

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.

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

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.

Scala syntax: why is anonymous function parameter type parsed differently using parenthesis versus curly braces?

Given Scala 2.12.6:
val list = List(1)
val x = 2
This works:
list.map ( y => x + y )
returning List[Int] = List(3)
and this works:
list.map ( (y: Int) => x + y )
returning the same value.
Same for this:
list.map { (y: Int) => x + y }
And same for this:
list.map { y: Int => x + y }
Yet this fails:
list.map ( y: Int => x + y )
producing the error:
error: not found: type +
list.map ( y: Int => x + y )
^
Why is Scala thinking the + is meant to indicate a type, and where is this difference between using parenthesis and curly braces documented and explained?
The Section 6.23 about anonymous functions says:
In the case of a single untyped formal parameter, (x) => e can be abbreviated to x => e. If an anonymous function (x: T) => e with a single typed parameter appears as the result expression of a block, it can be abbreviated to x: T => e.
Thus, in a block { ... }, the function literal (y: Int) => x + y can be abbreviated to just y: Int => x + y.
Without the block, the entire Int => x + y-part is treated as type ascription, so the error message actually makes sense. For example, here is a context in which the offending expression becomes valid:
type y = Unit
type x = Unit
type +[A, B] = Int
val y = (i: Int) => 42 + i
val list = List(1)
println(
list.map ( y: Int => x + y )
) // happily prints `List(43)`.
This is because there are two ys in two separate scopes (one value, one type alias), so that (y: Int => x + y) becomes (y: Int => +[x, y]), and then (y: Int => Int), which is just a type ascription enforcing that value y is indeed of function type Int => Int (which it is, so everything compiles and runs). Here is another similar example.
My suggestion: stick to the slightly more verbose (foo: Foo) => { ... } notation, it will cause fewer surprises for everyone who tries to read and to modify the code. Otherwise there is some risk that
argument types in bindings collide with type ascriptions
=> of the anonymous lambda collides with function type =>
arithmetic operation + collides with binary infix type constructor +[_,_]
values x, y collide with undefined types x, y.
The fact that same syntax can denote both types and expressions can be somewhat of a double-edged sword.

Why is this function called multiple times?

In this function "f" :
def f(x: => Int) : Int = x * x * x //> f: (x: => Int)Int
var y = 0 //> y : Int = 0
f {
y += 1
println("invoked")
y
} //> invoked
//| invoked
//| invoked
//| res0: Int = 6
"f" is invoked same amount of times as "x" parameter is multiplied.
But why is function invoked multiple times ?
Should "f" not expand to 1 * 1 * 1 not 1 * 2 * 3 ?
Your x is not a function, it is a by-name parameter, and its type is a parameterless method type.
Parameterless method type means the same as def x, something that is evaluated every time you reference it. By reference, we mean x and not x.apply() or x().
The expression you're passing to your function f is evaluated every time x is referenced in f. That expression is the whole thing in braces, a block expression. A block is a sequence of statements followed by the result expression at the end.
Here's another explanation: https://stackoverflow.com/a/13337382/1296806
But let's not call it a function, even if it behaves like one under the covers.
Here is the language used in the spec:
http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#by-name-parameters
It's not a value type because you can't write val i: => Int.
It was a big deal when they changed the implementation so you could pass a by-name arg to another method without evaluating it first. There was never a question that you can pass function values around like that. For example:
scala> def k(y: => Int) = 8
k: (y: => Int)Int
scala> def f(x: => Int) = k(x) // this used to evaluate x
f: (x: => Int)Int
scala> f { println("hi") ; 42 }
res8: Int = 8
An exception was made to "preserve the by-name behavior" of the incoming x.
This mattered to people because of eta expansion:
scala> def k(y: => Int)(z: Int) = y + y + z
k: (y: => Int)(z: Int)Int
scala> def f(x: => Int) = k(x)(_) // normally, evaluate what you can now
f: (x: => Int)Int => Int
scala> val g = f { println("hi") ; 42 }
g: Int => Int = <function1>
scala> g(6)
hi
hi
res11: Int = 90
The question is how many greetings do you expect?
More quirks:
scala> def f(x: => Int) = (1 to 5) foreach (_ => x)
f: (x: => Int)Unit
scala> def g(x: () => Int) = (1 to 5) foreach (_ => x())
g: (x: () => Int)Unit
scala> var y = 0
y: Int = 0
scala> y = 0 ; f { y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
scala> y = 0 ; g { y += 1 ; println("hi") ; () => y }
hi
y: Int = 1
scala> y = 0 ; g { () => y += 1 ; println("hi") ; y }
hi
hi
hi
hi
hi
y: Int = 5
Functions don't cause this problem:
scala> object X { def f(i: Int) = i ; def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
res12: Int = 0
scala> trait Y { def f(i: Int) = i }
defined trait Y
scala> object X extends Y { def f(i: => Int) = i+1 }
defined object X
scala> X.f(0)
<console>:11: error: ambiguous reference to overloaded definition,
both method f in object X of type (i: => Int)Int
and method f in trait Y of type (i: Int)Int
match argument types (Int)
X.f(0)
^
Compare method types:
http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types
This is not a pedantic distinction; irrespective of the current implementation, it can be confusing to think of a by-name parameter as "really" a function.
Another way of saying what has already been said is that inside f you invoke the function x three times. The first time it increments the y var and returns 1. The second time it again increments y returning 2 and the third time it again increments y and returns 3.
If you want it invoked only once then you may want to do something like this:
def f(x: => Int) : Int = x * x * x
var y = 0
lazy val xx = {
y += 1
println("invoked")
y
}
f {xx}
This will print 'invoked' only once and result in a returned value of 1.
x: T means need a T value.
x: => T means need a T value, but it is call by name.
x: () => T This means need a function given nothing to T
However, this question is not related to the difference between function and method.
The reason is call by name is invoked every time you try to use it.
change to call by value def f(x: Int) : Int, it will only invoke once.
Because you increment y by 1 every time the argument is used inside f
The result which your function f() returns is changing, because there is a global variable that is incremented with every subsequent call to that function.
the x in f(x: => Int) is interpreted as "some function that returns Int". So it has to be called 3 times to evaluate the x*x*x expression. With every call, you increment the global variable and return the result, which is how you arrive at three subsequent natural numbers (because the global variable is initialized to 0). Hence 1*2*3.

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.