Are partially applied functions and Closures orthogonal in Scala? - 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?

Related

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

How to define a type of function with default value in Scala

This is slightly different from this question.
I want to define a function type that have default value defined.
Like this:
trait Foo {
type MyFunction = (Int, Option[Int] = 0) => Boolean
def checkInts(f: MyFunction)
}
Is it possible? If yes, how can I achieve this? If not, why?
Read here why you can't have default arguments in anonymous functions and how to make something similar - In Scala, can you make an anonymous function have a default argument?
But if you just need a way to pass a function taking 2 or 1 argument, you can always use simpler approach:
trait Foo {
type MyFunc1 = (Int) => Boolean
type MyFunc2 = (Int, Int) => Boolean
def checkInts(f: MyFunc1)
def checkInts(f: MyFunc2)
// common code of checkInts could be in some private method
}
Based on my knowledge so far you cannot define a type with default parameters. A type is a type.
What you can do is define a partially applied function.
Taking as an example the following function:
scala> def factorOf(x: Int, y: Int) = y % x == 0
factorOf: (x: Int, y: Int)Boolean
If you want a shortcut to the function without retaining any parameters, you can use the wildcard operator (_) assignment
scala> val f = factorOf _
f: (Int, Int) => Boolean = <function2>
scala> val x = f(7, 20)
x: Boolean = false
If you want to retain some of the parameters, you can partially apply the function by using the wildcard operator to take the place of one of the parameters. The wildcard operator here requires an explicit type, because it is used to generate a function value with a declared input type:
scala> val multipleOf3 = factorOf(3, _: Int)
multipleOf3: Int => Boolean = <function1>
scala> val y = multipleOf3(78)
y: Boolean = true
The new function value, multipleOf3, is a partially applied function, because it contains some but not all of the parameters for the factorOf() function.
A cleaner way to partially apply functions is to use functions with multiple parameter lists. This is a technique
known as currying the function:
scala> def factorOf(x: Int)(y: Int) = y % x == 0
factorOf: (x: Int)(y: Int)Boolean
scala> val isEven = factorOf(2) _
isEven: Int => Boolean = <function1>
scala> val z = isEven(32)
z: Boolean = true

Why should calling a currying function with non-complete args with underscore

According to ScalaByExample:
A curried function definition def f (args1) ... (argsn) = E where n >
1 expands to
def f (args1) ... (argsn−1) = { def g (argsn) = E ; g }
Or, shorter, using an anonymous function:
def f (args1) ... (argsn−1) = ( argsn ) => E
Uncurried version:
def f(x: Int): Int => Int = {
y: Int => x * y
} //> f: (x: Int)Int => Int
def f1 = f(10) //> f1: => Int => Int
f1(5)
Curried version:
def g(x: Int)(y: Int) = {
x * y
} //> g: (x: Int)(y: Int)Int
def g1 = g(10) _ //> g1: => Int => Int
g1(5)
The question is, Why curried required the underscore in line #5 in the second code snippet.
You can find the explanation at Martin Odersky book: http://www.artima.com/pins1ed/functions-and-closures.html (search for "Why the trailing underscore").
In short this is because Scala is closer to Java in a lot of things, rather than functional languages where this is not required. This helps you to find out mistakes at compile time, if you forgot the missing argument.
If underscore was not required, the next code will compile:
println(g(10))
And this check helps you preventing such mistakes
There are some cases though, when such calls are obvious, and underscore is not required:
def g(x: Int)(y: Int) = {
x * y
}
def d(f: Int => Int) {
f(5)
}
d(g(10)) // No need to write d(g(2) _)
// Or any other way you can specify the correct type
val p: Int => Int = g(10)
Something to note: in Scala, def's are methods, not functions, at least, not directly. Methods are converted to functions by the compiler every time a method is used where a function would be required, but strictly speaking, a function would be created with val instead, like so:
val curry = (x: Int) => (y: Int) => x * y
This allows you to apply arguments one at a time without having to add a trailing underscore. It functions identically to the code in your first snippet, but because it uses val and not def, curry cannot be written like
val curry(x: Int) = (y: Int) => x * y //Won't compile
So, when you want to write a function that behaves the way you want a curried function to behave, write it like I did in my first snippet. You can keep chaining parameters with => as many times as you want (up to technical limits, but good luck hitting them).

Declare a function using def or var in Scala

I'm trying to figure out the difference between def and var/val when declaring a function in Scala.
Say we have a function:
scala> def f(x: Int) = { x * 2 }
f: (x: Int)Int
And another function g:
scala> var g = (x:Int) => x*2
g: Int => Int = <function1>
Apparently they are the same in the following way:
scala> f(2)
res0: Int = 4
scala> g(2)
res1: Int = 4
However, I could do
g = f
g: Int => Int = <function1>
but not
scala> f = g
<console>:13: error: missing arguments for method f;
follow this method with `_' if you want to treat it as a partially applied function
val $ires6 = f
^
<console>:10: error: reassignment to val
f = g
^
Question 1: why does this happen? I'm guessing that def maps to val.
Question 2: if I use val instead of var in declare g, are they equivalent? If not, what is the difference then?
I then try:
scala> def three( timetwo:(Int) => Int ) = { timetwo(3) }
three: (timetwo: Int => Int)Int
scala> three(g)
res47: Int = 6
scala> three(f)
res48: Int = 6
Question 3: does it mean (x: Int)Int is the same as Int => Int = <function1>? If so, is there some situation that we should favor one over the other?
Things is getting wired with the _ (underscore),
scala> three(f _)
res49: Int = 6
scala> three(g _)
<console>:11: error: type mismatch;
found : () => Int => Int
required: Int => Int
three(g _)
^
Question 4: why does this happen? What's the usage of _(underline) in Scala?
why does this happen? I'm guessing that def maps to val.
def is a method (in JVM terms) so it doesn't make sense to assign it.
The parser is then confused and it ultimately tries to save the day by interpreting the assignment f = g as
val $ires6 = f
f = g
Both statements are illegal, so you get two errors:
you can't assign a method to a val without an explicit type annotation or a _ expansion - see below)
you can't reassign a val (in case you are wondering, $ires6 is a fresh val introduced by the REPL)
if I use val instead of var in declare g, are they equivalent? If not, what is the difference then?
The difference is that val cannot be reassigned (i.e. it's a constant reference), whereas var can (i.e. it's a mutable reference).
More on the subject here: What is the difference between a var and val definition in Scala?
does it mean (x: Int)Int is the same as Int => Int = ? If so, is there some situation that we should favor one over the other?
Methods and functions are not the same, although the compiler does its best to make you believe they are, through a transformation called eta-expansion. In some cases such transformation can be performed automatically, in some others you need to be explicit and trigger it with a trailing _.
In your specific example (passing a method where a function is expected) the expansion can been performed automatically.
You can read this Q/A for a more in-depth discussion about which style to prefer.
why does this happen? What's the usage of _(underline) in Scala?
The underscore (_) has many uses in scala, one of which is the one I mentioned before, i.e. triggering the eta expansion of a method into a function.
That's a special syntax for methods, so you simply can't apply it to a function, as it would make no sense.
That's why you can do f _ (which will turn the f method into a function), but you can't do g _ (since g it's already a function).

Usefulness (as in practical applications) of Currying v.s. Partial Application in Scala

I'm trying to understand the advantages of currying over partial applications in Scala. Please consider the following code:
def sum(f: Int => Int) = (a: Int, b: Int) => f(a) + f(b)
def sum2(f: Int => Int, a: Int, b: Int): Int = f(a) + f(b)
def sum3(f: Int => Int)(a: Int, b: Int): Int = f(a) + f(b)
val ho = sum({identity})
val partial = sum2({ identity }, _, _)
val currying = sum3({ identity })
val a = currying(2, 2)
val b = partial(2, 2)
val c = ho(2, 2)
So, if I can calculate partially applied function that easy, what are the advantages of currying?
Currying is mostly used if the second parameter section is a function or a by name parameter. This has two advantages. First, the function argument can then look like a code block enclosed in braces. E.g.
using(new File(name)) { f =>
...
}
This reads better than the uncurried alternative:
using(new File(name), f => {
...
})
Second, and more importantly, type inference can usually figure out the function's parameter type, so it does not have to be given at the call site.
For instance, if I define a max function over lists like this:
def max[T](xs: List[T])(compare: (T, T) => Boolean)
I can call it like this:
max(List(1, -3, 43, 0)) ((x, y) => x < y)
or even shorter:
max(List(1, -3, 43, 0)) (_ < _)
If I defined max as an uncurried function, this would not work, I'd have to call it like this:
max(List(1, -3, 43, 0), (x: Int, y: Int) => x < y)
If the last parameter is not a function or by-name parameter, I would not advise currying. Scala's _ notatation is amost as lightweight, more flexible, and IMO clearer.
I think it becomes clearer if you invert your curried example:
def sum4(a: Int, b: Int)(f: Int => Int): Int = f(a) + f(b)
val d = sum4(2, 2) { x =>
x * x
}
It is more of an optical effect but you don’t need to use any parentheses around the whole expression. Of course you can achieve the same result using partial application or by creating a helper method to invert the arguments, sure. The point is, that you don’t have to do all of this if you start with a curried method in the first place. In that sense currying is more of an API and syntax sugar thing. It is not expected that you use
val partial_sum4 = sum4(2, 2)
anywhere in your code or that this is in any way especially meaningful to do. It is just that you get a nicely looking expression easily.
(Well, and there are some advantages with respect to type inference…)