Why the function call never gets executed? - scala

I have a function defined like
def counter(x: Int) = {
var i = x
() => {
i = i + 1
println(i)
}
}
val count = counter(0)
So count is a function taking no parameter returning Unit. Then the parenthesis could be omitted when calling count. But if I call it by just saying count, i in fact will not be added and nothing happens. In the meantime, a compiler warning will be given like "A pure expression does nothing you may be omitting the parenthesis".
If I call it with parentheses like count(), everything is all right and increased i will be printed.
Why saying count doesn't work? Thank you.

You can't call function without parentheses. In scala you can call method without arguments with no parentheses. Method, but not function.
Actually "call function" means "call method apply of object of type FunctionN" in scala.
So count() means count.apply(). You can call method apply with no parentheses like this: count.apply.

Your counter(x:Int) method actually returns the function () => { ... } you have defined (which returns Unit and generates the compiler warning).
So by calling count with parentheses, you actually execute the function.
If I desugar type inference, you obtain:
def counter(x: Int): () => Unit = {
var i = x
() => {
i = i + 1
println(i)
}
}
val count: () => Unit = counter(0)

A Function0 does not correspond to a parameterless method exactly. That is to say:
val returnOne = () => 1
// approximates
def returnOne() = 1
// rather than
def returnOne = 1
In fact, once you lift a parameterless method to a Function0 the parameterless method behavior is lost:
// Define a parameterless method
scala> def returnOne = 1
returnOne: Int
// Every time you reference the method it is evaluated
scala> returnOne
res2: Int = 1
// Lift the method to a Function0
scala> returnOne _
res3: () => Int = <function0>
// Now a reference to the lifted method evaluates to the lifted method
scala> res3
res4: () => Int = <function0>
// And you have to invoke it explicitly
scala> res3()
res5: Int = 1

Related

Is def considered a closure in Scala?

I want to understand the difference between the closure declared as val and the one declared as method (with the def kyeword). What's exactly the difference between theses two functions, is the ep method a closure ?
scala > var more=10
scala > val phi= (x:Int)=>x+more
scala > def ep(x:Int):Int= x+more
A function object that captures free variables, and is said to be
“closed” over the variables visible at the time it is created is called closure. For example:
var foo = 10
val bar = (x:Int) => x+foo
Here, foo is free variable in function literal and hence the function literal is open term. As a result, val bar is a closure since function value (object) is created with open term foo.
Now, lets start with different between val and def in term of function definition.
In scala, function is a value and you can assign it to variable.
When you define a function with val, you are defining it with a function literal as val bar = (x:Int) => x+foo, which return a function object and assign it as value to bar. In case of val, the function value is evaluated as it is defined. That means, function literal (x:Int) => x+foo is evaluated to function value with free variable foo and is stored in bar variable as closure.
//In the following snippet, a function literal is evaluated to object Function1 and assigned to val bar.
scala> var foo = 10
foo: Int = 10
scala> val bar = (x: Int) => x + foo
bar: Int => Int = <function1> //Function1 object is returned
Since, bar is a value and is evaluated as it is defined, it will always refer to same object in the memory whenever accessed.
scala> bar eq bar //because both instance refer to same instance.
res11: Boolean = true
On the other hand, you define a method with def and method is not a function in Scala. According to Scala language specification, method do not have type in Scala hence it cannot be used as value.
For example, you cannot do as:
val bar = {def foo(x:Int): Int = x + 1 }
However, according to Specification, if method name is used as value, then Scala implicitly converts it to corresponding function type with ETA Expression. e.g. method def a: Int is converted as a: => Int. That means, every time you call method, it returns a function value.
scala> def foo():Int = 1
a: ()Int
scala> val bar:( ()=> Int) = foo
bar: () => Int = <function0> //foo return Function0
//Note, val bar = foo, will assign the value returned by foo instead of returning function, so specify type.
Because of this, method can be used as function. For example, when ever some method or function require a function type as argument, you can provide def method.
scala> val foo = (x:Int, double:Function1[Int, Int]) => double(x)
foo: (Int, Int => Int) => Int = <function2>
scala> def double(x:Int):Int = x * 2
double: (x: Int)Int
scala> foo(3, double)
res1: Int = 6
In addition, note that with method, you get a new function on every call.
scala> def double: Int => Int = _ * 2
double: Int => Int
scala> double eq double
res15: Boolean = false //false because every time double refers to new instance and hence is not equal unlike val.
Now, lets go to closure.
Both function literal defined with val and def method return function value (object). The function value (the object) that’s created at runtime from function literal is closure. On the other hand, a method is not a closure, but the function value you get from calling a method is a closure.
scala> var more = 1
more: Int = 1
scala> val foo = (x:Int) => x + more // foo is clouser.
foo: Int => Int = <function1>
scala> def bar(x:Int):Int = x + more // bar is not clouser.
bar: (x: Int)Int
scala> val barClouser : (Int => Int) = bar // barClouser is clouser.
barClouser: Int => Int = <function1>
scala> val barValue = bar(3) // bar is converted to clouser and then clouser value is evaluated and result is assigned to barValue variable.
barValue: Int = 4
scala> val fooValue = foo(3) //foo value is evaluated and returned as value which is assigned to fooValue variable.
fooValue: Int = 4

How to get value out of anonymous function in scala?

I am trying to learn scala and understand difference between functions and methods.
Here is very simple code I wrote -
scala> class C ( acc:Int) {
| val minc = ( acc + 1 )
| val func = { () => acc += 3 }
| }
scala> val c1 = new C(3)
c1: C = C#55e610e3
scala> c1.minc
res2: Int = 4
scala> c1.func
res3: () => Int = <function0>
I understand that result of calling function func on instantiated object c1 is stored as another expression res3.
However I want to get value out of of anonymous function () = acc +3 that is inside class C.
If I try to pass argument to res3 expression scala throws an error
scala> res3(4)
<console>:11: error: too many arguments for method apply: ()Int in trait Function0
res3(4)
^
How to get value out of it ?
PS - I have just started with scala and don't know if this is at all possible or not ?
This is your definition of func:
val func = { () => acc += 3 }
Let's take a look in the REPL at what is the type of func.
scala> val c1 = new C(3)
val c1 = new C(3)
c1: C = C#58db88e9
scala> c1.func
c1.func
res29: () => Unit = <function0>
In plain English, this means "func refers to a function that accepts no arguments and doesn't return a value." Unit means the method doesn't return anything. If you're coming from Java, then it's analogous to void as the return type. function0 means it accepts 0 arguments.
Next, let's take a look at the failing call in your example.
scala> c1.func(4)
c1.func(4)
<console>:10: error: too many arguments for method apply: ()Unit in trait Function0
c1.func(4)
^
Now that we know the method signature of func, this error message should make more sense. We know that func refers to a function that accepts no arguments, yet in this call, you have attempted to call it with a single integer argument. Since the method call has too many arguments, Scala correctly reports this as an error.
I am not entirely sure what you were trying to do by passing 4 as an argument. My best guess is that you are trying to apply the function to calculate its result by adding 3 to acc and then returning it to the caller. If I'm right, then we can redefine C as this:
class C(var acc:Int) {
val minc = ( acc + 1 )
val func = () => {
acc += 3
acc
}
scala> val c1 = new C(3)
val c1 = new C(3)
c1: C = C#58db88e9
scala> c1.func()
c1.func()
res44: Int = 6
When we call c1.func(), no arguments are passed, so it correctly matches the defined method signature.
Another possibility is that you were trying to parameterize the increment amount and pass 4 to it in the call. If so, then you can do this:
class C(var acc:Int) {
val minc = ( acc + 1 )
val func = (delta: Int) => {
acc += delta
acc
}
}
scala> c1.func(4)
c1.func(4)
res45: Int = 7
In this case, we have declared that the anonymous function accepts 1 argument of type Int, so when we pass 4 in the method call, it correctly matches the method signature.
You're not declaring an anonymous function in the way you think. This line:
val func = { () => acc += 3 }
That actually declares 2 anonymous functions. The brackets are the first anonymous function (that takes no arguments), and the () => acc += 3 is the second function. Scala allows you to declare a 0-arity anonymous function by just using brackets. If you drop those, you'll have what you want:
val func = () => acc += 3
As a bit of a side note, you can see this in the type signature. Your current signature for func is:
() => Int = <function0>
That's a function that takes 0 arguments and returns an integer. That's not what you want. When you change it to what I gave you, you'll get this:
Int => Int = <function1>
Now func takes a single argument, and Integer, and returns another Integer, which is what you wanted.

what is wrong with this partially applied function attempt?

I am trying to write a partially applied function. I thought the below would work but it doesn't. Grateful for any help.
scala> def doSth(f: => Unit) { f }
doSth: (f: => Unit)Unit
scala> def sth() = { println ("Hi there") }
sth: ()Unit
scala> doSth(sth)
Hi there
scala> val b = sth _
b: () => Unit = <function0>
scala> doSth(b)
<console>:11: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
doSth(b)
^
Thanks!
The difference is subtle. sth is a method, so you can call it without the parentheses, which is what is happening here:
doSth(sth)
But b is just a function () => Unit, which you must use the parentheses to invoke.
doSth(b())
Otherwise you would not be able to assign b to another identifier.
val c: () => Unit = b
If we automatically invoked b here, c would be Unit instead of () => Unit. The ambiguity must be removed.
Let me also clarify that doSth is not a method that accepts only functions. f: => Unit means it accepts anything that evaluates to Unit, which includes methods that return Unit when they are invoked. doSth(sth) is not passing the message sth to doSth, it's invoking sth without parentheses and passing the result.
I think the difference is that b has type () => Unit, and doSth expects an expression that returns Unit (minor difference). If you want to store sth as a variable without the side effects, you could do:
lazy val b = sth
doSth(b)
The other option would be to make it so that doSth takes in () => Unit:
def doSth(f: () => Unit) { f() }
def sth() = { println ("Hi there") }
doSth(sth)
val b = sth _
doSth(b)

What is the difference between "def" and "val" to define a function

What is the difference between:
def even: Int => Boolean = _ % 2 == 0
and
val even: Int => Boolean = _ % 2 == 0
Both can be called like even(10).
Method def even evaluates on call and creates new function every time (new instance of Function1).
def even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = false
val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
With def you can get new function on every call:
val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1049057402
test()
// Int = -1049057402 - same result
def test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -240885810
test()
// Int = -1002157461 - new result
val evaluates when defined, def - when called:
scala> val even: Int => Boolean = ???
scala.NotImplementedError: an implementation is missing
scala> def even: Int => Boolean = ???
even: Int => Boolean
scala> even
scala.NotImplementedError: an implementation is missing
Note that there is a third option: lazy val.
It evaluates when called the first time:
scala> lazy val even: Int => Boolean = ???
even: Int => Boolean = <lazy>
scala> even
scala.NotImplementedError: an implementation is missing
But returns the same result (in this case same instance of FunctionN) every time:
lazy val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
lazy val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1068569869
test()
// Int = -1068569869 - same result
Performance
val evaluates when defined.
def evaluates on every call, so performance could be worse than val for multiple calls. You'll get the same performance with a single call. And with no calls you'll get no overhead from def, so you can define it even if you will not use it in some branches.
With a lazy val you'll get a lazy evaluation: you can define it even if you will not use it in some branches, and it evaluates once or never, but you'll get a little overhead from double check locking on every access to your lazy val.
As #SargeBorsch noted you could define method, and this is the fastest option:
def even(i: Int): Boolean = i % 2 == 0
But if you need a function (not method) for function composition or for higher order functions (like filter(even)) compiler will generate a function from your method every time you are using it as function, so performance could be slightly worse than with val.
Consider this:
scala> def even: (Int => Boolean) = {
println("def");
(x => x % 2 == 0)
}
even: Int => Boolean
scala> val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>
scala> even(1)
def
res9: Boolean = false
scala> even2(1)
res10: Boolean = false
Do you see the difference? In short:
def: For every call to even, it calls the body of the even method again. But with even2 i.e. val, the function is initialized only once while declaration (and hence it prints val at line 4 and never again) and the same output is used each time it accessed. For example try doing this:
scala> import scala.util.Random
import scala.util.Random
scala> val x = { Random.nextInt }
x: Int = -1307706866
scala> x
res0: Int = -1307706866
scala> x
res1: Int = -1307706866
When x is initialized, the value returned by Random.nextInt is set as the final value of x. Next time x is used again, it will always return the same value.
You can also lazily initialize x. i.e. first time it is used it is initialized and not while declaration. For example:
scala> lazy val y = { Random.nextInt }
y: Int = <lazy>
scala> y
res4: Int = 323930673
scala> y
res5: Int = 323930673
See this:
var x = 2 // using var as I need to change it to 3 later
val sq = x*x // evaluates right now
x = 3 // no effect! sq is already evaluated
println(sq)
Surprisingly, this will print 4 and not 9! val (even var) is evaluated immediately and assigned.
Now change val to def.. it will print 9! Def is a function call.. it will evaluate each time it is called.
val i.e. "sq" is by Scala definition is fixed. It is evaluated right at the time of declaration, you can't change later. In other examples, where even2 also val, but it declared with function signature i.e. "(Int => Boolean)", so it is not Int type. It is a function and it's value is set by following expression
{
println("val");
(x => x % 2 == 0)
}
As per Scala val property, you can't assign another function to even2, same rule as sq.
About why calling eval2 val function not printing "val" again and again ?
Orig code:
val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
We know, in Scala last statement of above kind of expression (inside { .. }) is actually return to the left hand side. So you end up setting even2 to "x => x % 2 == 0" function, which matches with the type you declared for even2 val type i.e. (Int => Boolean), so compiler is happy. Now even2 only points to "(x => x % 2 == 0)" function (not any other statement before i.e. println("val") etc. Invoking event2 with different parameters will actually invoke "(x => x % 2 == 0)" code, as only that is saved with event2.
scala> even2(2)
res7: Boolean = true
scala> even2(3)
res8: Boolean = false
Just to clarify this more, following is different version of the code.
scala> val even2: (Int => Boolean) = {
| println("val");
| (x => {
| println("inside final fn")
| x % 2 == 0
| })
| }
What will happen ? here we see "inside final fn" printed again and again, when you call even2().
scala> even2(3)
inside final fn
res9: Boolean = false
scala> even2(2)
inside final fn
res10: Boolean = true
scala>
Executing a definition such as def x = e will not evaluate the expression e. In- stead e is evaluated whenever x is invoked.
Alternatively, Scala offers a value definition
val x = e,which does evaluate the right-hand-side as part of the evaluation of the definition.
If x is then used subsequently, it is immediately replaced by the pre-computed value of e, so that the expression need not be evaluated again.
also, Val is a by value evaluation. Which means the right-hand side expression is evaluated during definition. Where Def is by name evaluation. It will not evaluate until it's used.
In addition to the above helpful replies, my findings are:
def test1: Int => Int = {
x => x
}
--test1: test1[] => Int => Int
def test2(): Int => Int = {
x => x+1
}
--test2: test2[]() => Int => Int
def test3(): Int = 4
--test3: test3[]() => Int
The above shows that “def” is a method (with zero argument parameters) that returns another function "Int => Int” when invoked.
The conversion of methods to functions is well explained here: https://tpolecat.github.io/2014/06/09/methods-functions.html
In REPL,
scala> def even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean
scala> val even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean = $$Lambda$1157/1017502292#57a0aeb8
def means call-by-name, evaluated on demand
val means call-by-value, evaluated while initialization
Note: There are different types of functions in Scala: abstract, concrete, anonymous, high order, pure, impure etc...
Explaining val function:
A val function in Scala is a complete object. There are traits in Scala to represent functions with various numbers of arguments: Function0, Function1, Function2, etc. As an instance of a class that implements one of these traits, a function object has methods. One of these methods is the apply method, which contains the code that implements the body of the function.
When we create a variable whose value is a function object and we then reference that variable followed by parentheses, that gets converted into a call to the apply method of the function object.
Explaining Method i.e def:
Methods in Scala are not values, but functions are.
A Scala method, as in Java, is a part of a class. It has a name, a signature, optionally some annotations, and some bytecode.
The implementation of a method is an ordered sequence of statements that produces a value that must be compatible with its return type.

Function parameter types and =>

What exactly that declaration of method parameter means:
def myFunc(param: => Int) = param
What is meaning of => in upper definition?
This is so-called pass-by-name. It means you are passing a function that should return Int but is mostly used to implement lazy evaluation of parameters. It is somewhat similar to:
def myFunc(param: () => Int) = param
Here is an example. Consider an answer function returning some Int value:
def answer = { println("answer"); 40 }
And two functions, one taking Int and one taking Int by-name:
def eagerEval(x: Int) = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy"); x; }
Now execute both of them using answer:
eagerEval(answer + 2)
> answer
> eager
lazyEval(answer + 2)
> lazy
> answer
The first case is obvious: before calling eagerEval() answer is evaluated and prints "answer" string. The second case is much more interesting. We are actually passing a function to lazyEval(). The lazyEval first prints "lazy" and evaluates the x parameter (actually, calls x function passed as a parameter).
See also
Scala Returning a void function with 0 parameters, ugly syntax?
Just to make sure there is an answer that uses the proper term: the Scala Language Specification uses the term call-by-name:
The type of a value parameter may be prefixed by =>, e.g. x: => T . The type of
such a parameter is then the parameterless method type => T . This indicates that
the corresponding argument is not evaluated at the point of function application, but
instead is evaluated at each use within the function. That is, the argument is
evaluated using call-by-name.
-- Section 4.6.1 of the Scala Language Specification
To add to Tomasz Nurkiewicz's answer above, the difference I encounter between () => Int and => Int is that the second allows calling with bare blocks:
scala> def myfunc(f : () => Int ) = println("Evaluated: " + f )
myfunc: (f: () => Int)Unit
scala> def myfunc2(f : => Int ) = println("Evaluated: " + f )
myfunc2: (f: => Int)Unit
scala> myfunc({1})
<console>:9: error: type mismatch;
found : Int(1)
required: () => Int
myfunc({1})
^
scala> myfunc2({1})
Evaluated: 1