Function parameter types and => - scala

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

Related

Scala lambda function not resolved when declares the type of parameter?

when defining method in Scala, I found this
def method1: Int => Int = (j: Int) => j // works
def method2: Int => Int = j => j // works
def method3: Int => Int = j: Int => j // error
def method4: Int => Int = {j: Int => j} // works
Can anyone explain why method3 does not work? Is there any ambiguity in it?
One possible explanation is indeed that this restriction avoids ambiguity: x: A => B could be understood as an anonymous function that takes a parameter x of type A and returns the object B. Or it could be understood as "casting" a variable x to the type A => B. It is very rare that both of these would be valid programs, but not impossible. Consider:
class Foo(val n: Int)
val Foo = new Foo(0)
val j: Int => Foo = new Foo(_)
def method1: Int => Foo = (j: Int) => Foo
def method2: Int => Foo = j: Int => Foo
println(method1(1).n)
println(method2(1).n)
This actually compiles and prints:
0
1
All of these variants are covered by Anonymous Functions section of the specification. The relevant part is
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.
In method3, the function isn't the result expression of a block; in method4 it is.
EDIT: oops, presumably you meant why the limitation is there. I'll leave this answer for now as stating what the limitation is exactly, and remove it if anyone gives a better answer.

Unsure how this returns an Int of functions

I'm reading this scala book and a bit unsure on what this syntax translates to:
def bf: Int => Int => Int = i => v => i + v
bf is the name of the function.
after then colon is the function return type which is:
Int => Int => Int
I presume that the equal sign is the start of the function body, but not sure because then it has i => v => i + v.
Can someone clarify where each return type is and how to you break it down in your head so I can do the same :)
Short answer:
return type of the code can be read as Int => (Int => Int).
It is a function that takes single parameter of Int and returns a function that takes another Int parameter and returns Int.
If you are still getting confused, this is the longer way to write the same.
val bf: Int => (Int => Int) = (a:Int) => ((b: Int) => a + b)
|_________________| |____________________________|
type outer function
|________________|
inner func returned by the outer func
Long answer:
It is normally called curried function or function currying.
I assume You already noticed this though, This method originally trying to get sum of 2 Int values which is written as below.
val foo = (a: Int,b: Int) => a + b
any functions which takes multiple parameters can be transformed to nested single parameter functions a.k.a "curried function".
You may write it by your self just like your question code but You can call .curried to the method/function to get it as well.
val bf = foo.curried //bf is exactly the same thing as you wrote
This is usually used when you can't define both of the parameters at the same time so when you gets first value, make a function that (b: Int) => YOUR_FIRST_VALUE_ALREADY_DEFINED + b. and call it when you get second value.
How the curried function is used...
bf(4)(5) //9
val bar = bf(6) // (Int) => Int
bar(7) // 13
functional types are associate to the right.
for e.g.
Int => Int => Int is equivalent to Int => (Int => Int)
more details you can register and go through below lecture.
https://www.coursera.org/learn/progfun1/lecture/fOuQ9/lecture-2-2-currying

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.

Why need I denote the type for partial applied function on the known type parameter?

Given the
def sum(a: Int, b: Int) = a + b
val add7 = sum(7, _)
// compiler complains missing $x1's type for $x1 => sum(7, $x1)
val add8 = sum(8, _: Int)
// fine
And curried sum can do this without type declaration .
def sum_curry(a: Int)(b: Int) = a + b
val add9 = sum_curry(9)(_)
// fine
But it's not a generic function, what sum's parameter types can be known and it is already there.
Why cannot Scala know the $x1's type from b: Int in sum's signature?
The compiler needs to know the data types of function arguments to map a function call to exactly one function definition (out of many overloaded function definition of with same name)
It will become ambiguous if we try a reverse mapping from function definition to function call to determine the type of a parameter in function call.
Eta expression can convert this to a value type (Int, Int) => Int only when:
_ as in place of the argument of list
val f = sum _
or, you just omit the argument list.
val f :(Int, Int) => Int = sum
and specify its type.
or use each _
val f = sum(_ , _)
As you can see, sum(7, _) cannot satisfy any of above.

How to define scala type for no argument function?

This works
def func(f: => Int) = f
This dosn't (inside class for example)
type EmptyFunct = => Int
or
type EmptyFunct = (=> Int)
Scala version 2.9
Two questions:
Why dosn't syntax sugar work in second case?
How to define this function without syntax sugar?
=> Int is not exactly a function without parameter, it is an Int argument with call by name passing convention. (Of course, that is rather fine a point, as it is implemented by passing a function without parameter ).
The function without argument is written () => Int. You can do type EmptyFunct = () => Int.
It is not a type. Inside func, f will be typed as an Int. An argument of type () => Int will not.
def func(f: => Int) = f *2
func (: => Int) Int
But
def func(f: () => Int) : Int = f*2
error: value * is not a member of () => Int
You should use Function0
In the first case it does not work because you declare a non argument Function but because you indicates that the parameter is called by name.
I don't see much sense in a method, returning an int, invoked with no parameter. Either it returns a constant, so you could use the constant, or it would use a var?
So let's go with a var:
var k = 10
val fi = List (() => k * 2, () => k - 2)
val n = fi(0)
n.apply
k = 11
n.apply
result is 20, then 22.