Difference between val and def in scala? - scala

I am starting with scala and have this confusion in evaluation. If in val, the result is evaluated when declared then why on calling that val name it again gives me the body of the function.
scala> val pop = (x:Int,y:Int)=> println(s"$x $y is the number")
pop: (Int, Int) => Unit = <function2>
scala> pop(12,3)
12 3 is the number
scala> pop(12,3) //So is this expression evaluated again ? and if not how is it stored in the memory that if 12 and 3 will come as parameter then that value will be given back.
12 3 is the number
scala> pop
res6: (Int, Int) => Unit = <function2>
//why is it giving the body as it is already evaluated
Can a function with no parameters using val can be declared?
val som....which only prints say hello

In Scala, function are first-class values so the value of pop is
(x:Int, y:Int) => println(s"$x $y is the number")
itself. Such a function-value might look very different from say value 42 but is nevertheless a regular value. For example, contrast the following
val i: Int = 42 // assigning value 42 to name i
val f: Int => String = i => "foo" // assigning value `i => "foo"` to name f
It might become clearer if we desugar pop definition to
val pop: Function2[Int, Int, Unit] = new Function2[Int, Int, Unit] {
def apply(x: Int, y: Int): Unit = println(s"$x $y is the number")
}
where we see pop is assigned an instance of Function2 class which contains an apply method. Furthermore pop(12, 3) desugars to
pop.apply(12,3)
where we see pop(12, 3) simply calls a method on Function2 class. Contrast the evaluation of pop
pop
res6: (Int, Int) => Unit = <function2>
with function application of a function instance pop points to
pop(12,3)
12 3 is the number
pop is a value definition in the sense that we cannot change the function it points to, for example,
pop = (i: Int) => i.toString // error: reassignment to val
Function with no parameters can be defined like so
val g = () => "I am function with no parameters"
g // evaluates g
g() // applies function pointed to by g

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

scala function literal and methods and underscore

I have a very simple piece of code that I am not able to get grasp of. I am reading function literals, and methods. I am doing this in repl.
scala> val v = (a:Int, b:Int, c:Int) => {a+b+c}
v: (Int, Int, Int) => Int = $$Lambda$1368/1731643198#4ae730ca
scala> val v1 = v(1,2,_:Int)
v1: Int => Int = $$Lambda$1369/903167315#93d6f4
scala> v1 (10)
res29: Int = 13
scala>
scala> val v2 = v _
v2: () => (Int, Int, Int) => Int = $$Lambda$1370/5485285#7dd5d17a
scala> val v3 = v2()
v3: (Int, Int, Int) => Int = $$Lambda$1368/1731643198#4ae730ca
scala> val v4 = v3(1,2,3)
v4: Int = 6
scala> def sumMe(a:Int, b:Int, c:Int) = { a+b+c}
sumMe: (a: Int, b: Int, c: Int)Int
scala> val v7 = sumMe _
v7: (Int, Int, Int) => Int = $$Lambda$1371/906350712#6c86938f
scala> v7(1,2,3)
res30: Int = 6
I need some help in understanding on what happens above. I will start from the bottom of the code. When I create the method sumMe and assign it to "v7" with "_" on the right, I know I am not executing the method. The output of val v7= sumMe_ is quite clear to me as it simply tells me that v7 will take 3 params, and return an int. It feels OK so far.
Now when I go to my `val v1 = v(1,2,_:Int), I can still correlate that it will create a function object and assign to v1 and in fact I am using Scala
s Function1's apply method is what I view it as.
I am hoping I understand it right so far. If my understanding above is right, what causes the most confusion is val v2 = v _. And based on the output of what I see I have to call this thing differently. Basically I am not able to understand why v2 is different from v7. v2 takes no arguments and gives me a function which I can call. If that is always the case with function literals of the kind that I have defined as val v = ..., then when I do val v1 = v(1,2,:_Int) why don't I get this from scala v1:()=>Int=>Int which is similar to v2's case.
And lastly, why won't v7=sumMe _ not give me the same output as val v2 = v_
In Scala, we differentiate methods from functions. When you define sumMe, you're defining a method, while your other declarations are functions. Methods, in Scala, are non value types, meaning the method itself has no value. When you try to assign it to a value, there is an implicit conversion called eta expansion that is done to convert it to the corresponding function type. From the specification:
Method types do not exist as types of values. If a method name is used
as a value, its type is implicitly converted to a corresponding
function type.
Now that we're equipped with the knowledge of methods and functions, lets analyze what happens.
When I create the method sumMe and assign it to "v7" with "_" on the right, I know I am not executing the method
That's right. When you do sumMe _, you're using eta-expansion to convert the method to a function.
Now when I go to my val v1 = v(1, 2, _: Int), I can still correlate that
it will create a function object and assign to v1
Again, you're right. v1 is now a partially applied function of type Function1[Int, Int].
Basically I am not able to understand why v2 is different from v7.
What is v2? It is a function object which was created by partially applying an existing function object. Since this function of type Function3[Int, Int, Int, Int] is already fixed in it's parameter list, partially applying it only nests it in another function object, now of type Function0, making it a Function0[Function3[Int, Int, Int, Int]].
In Scala, functions are value that means you can assign any function in a variable. Whenever you apply placeholder("_") in front of def it will convert def into function with same input and output types. If you apply placeholder in front of value it will convert into function that take unit as input and return value as output**[() => T]**. for example:
scala> val a = 2
a: Int = 2
scala> val fun1 = a _
fun1: () => Int = <function0>
scala> def sum(a:Int, b:Int) = a+ b
sum: (a: Int, b: Int)Int
scala> val fun2 = sum _
fun2: (Int, Int) => Int = <function2>
whenever you are trying to pass partial input parameters in a "def" it will return partial applied function. For example:
scala> val fun3 = sum(1,_:Int)
fun3: Int => Int = <function1>
fun3 is called partial applied function.
There are something need to clear for function and method,
function: we use val and var to define the function, it's often is an Anonymous Function, In Scala, there are Function0, Function1, Function2 ... for these Anonymous Function, and the function type like: (T0, T1...TN) => U.
so function v actually is a Function3 with 3 parameters.
method: it's used to def to declare with method body with the parameters and return type.
For val v2 = v _ actually equals to val v2 = () => v, in there wildcard _ will expand to () => v, and v2 means it's a function to create another function(v) without parameter.So val v3 = v2() means invoke v2() to create v function, so essentially v3 equal to v.
For val v7 = sumMe _ this means convert method sumMe to a function, in there wildcard _ will expand to (a: Int, b: Int, c: Int) => sumMe(a, b, c) , so sumMe _ will create a new function that's essentially equal to v, if you use v7 _ it also will create the same function like val v2 = v _.
Reference:
Difference between method and function in Scala

Are partially applied functions and Closures orthogonal in Scala?

Suppose I have the following code:
val someNumbers = List(-11, -10, -5, 0, 5, 10)
someNumbers.foreach( println _ )
val j = 10
(x: Int) => x + j
My question is Are partially applied functions and Closures orthogonal in Scala? This presentation seems to suggest that they are.
EDIT: 13 July 2014 [Changed code above]
It's really easy to see what's being returned when you go into the repl:
scala> type IntPairPred = (Int, Int) => Boolean
defined type alias IntPairPred
scala> val gt: IntPairPred = _ > _
gt: IntPairPred = <function2>
scala> gt(2,3)
res3: Boolean = false
What gt is, is a function2 i.e. a function that takes 2 parameters
Here's another example:
scala> def fn(a: Int, b: Int) = () => a + b
fn: (a: Int, b: Int)() => Int
scala> val a = fn(2,3)
a: () => Int = <function0>
What fn returns, is a function0 i.e. a function that doesn't take any parameters
Sorry but your example doesn't seem to refer to partial application, at least to me.
You're just using some shortcut syntax to define regular functions.
Actually gt, ge, ... definitions are expanded to something pretty like
val gt: IntPairPred = (x: Int, y: Int) => x > y
val gt: IntPairPred = (x: Int, y: Int) => x >= y
//and so on...
Regular functions support modification of its arguments, but this is not what you're looking for, I presume.
To define a closure, you should define a partial function referring to a variable in the outer scope, like
var one = 1
val gt1 = gt(1, _: Int)
assert(gt1(0)) //ok
assert(!gt1(1)) //ok
one = 2 //weirdo!
assert(gt1(0)) //ok
assert(gt1(1)) //ok
assert(!gt1(2)) //ok
So the point is not in functions definition or partial application. The point is if, at definition time, you're using variables from the closing scope within your function. In this case your function is influenced by the variable you closed over.
Is this what you were after?

Invoking functions returned by methods that take implicits

Given the following function:
def foo()(implicit count: Int): (String => Seq[String]) = {
s => for (i <- 1 until count) yield s
}
Calling apply() on the result explicitly works:
implicit val count = 5
val x = foo().apply("x") // <- works fine
And setting the result to a val, which you then call as a function, works:
val f: String => Seq[String] = foo()
f("y") // <- works fine
But trying to do it all in one line, without apply, confuses the compiler into thinking you're passing the implicit explicitly:
val z = foo()("z") // type mismatch; found: String("z"), required: Int
Is there a way to do this without either the explicit apply or the intermediate val? For instance, is it possible somehow to move the implicit declaration into the returned anonymous function?
scala> (foo() _)("z")
res10: Seq[String] = Vector(z, z, z, z)

Functions without arguments, with unit as argument in scala

def foo(x: Int, f: Unit => Int) = println(f())
foo(2, { Unit => 3 + 4 })
// case 1
def loop: Int = 7
foo(2, loop) // does not compile
changing loop to
// case 2
def loop(): Int = 7
foo(2, loop) // does not compile
changing loop to
// case 3
def loop(x: Unit): Int = 7 // changing according to Don's Comments
foo(2, loop) // compiles and works fine
Shouldn't case 1 and case 2 also work? Why are they not working?
Defining foo as
def foo(x: Int, y: () => Int)
then case 2 works but not case 1.
Arent they all supposed to work, defining the functions either way?
Also I think () => Int in foo is a bad style, y:=> Int does not work. Comments?
Scala distinguishes between the following things:
Functions/methods with no parameter lists ("by-name parameter" if a function)
Functions with one empty parameter list
Functions with one parameter of type Unit
None of these are equivalent, although as a convenience Scala allows you to elide empty parameter lists. (Incidentally, two empty parameter lists are also not the same.)
So, even though Unit is written (), this is not the same as the function argument parens () for a function or method. Instead, think of () as a Tuple0.
So, if you say f: Unit => Int, what you mean is "f takes one parameter, but it's a really boring parameter because it is Unit, which must always be the same boring Tuple0 value ()". What you're writing is really short for f: (Unit) => Int.
If you say f: () => Int, then you mean that "f takes no parameters and produces an Int".
If you say f: => Int, then you mean that "delay the execution of whatever statement produces an Int value until we use it in this code (and re-evaluate it each time)". Functionally, this ends up being basically the same as f: () => Int (and internally is converted into the same Function0 class), but it has a different usage, presumably to allow for a more compact form of closures (you always omit the => in the calling code).
()=>Int is Function0[Int] while Unit=>Int is Function1[Unit,Int]
scala> val function0: () => Int = () => 5
function0: () => Int = <function0>
scala> val function1: Unit => Int = u => 5
function1: (Unit) => Int = <function1>
scala> function0()
res0: Int = 5
scala> function1("anything")
res1: Int = 5
scala> function1(100)
res2: Int = 5
scala>
Also note that () is an object of Unit
scala> function1(())
res11: Int = 5
scala> function1 ()
res12: Int = 5
scala> function1()
res13: Int = 5
scala> val unit = ()
unit: Unit = ()
scala> function1(unit)
res15: Int = 5
scala> function1 apply unit
res16: Int = 5
scala>
In case 1 and 2 above, the return value of loop rather than loop itself is type checked for the second argument to foo and fails: Int != Unit => Int
The change to loop has a typo.