Returning a partially applied function in Scala - scala

Having a function f defined as:
def f(i1: Int, i2: Int)(i3: Int) = i1 + i2 + i3
It is possible to define a partially applied function as follows using _:
val f12 = f(1, 2) _ // f12: Int => Int = <function>
f12(3) // res0: Int = 6
Now when I return a partially applied function from a function, I do not need to use _:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) // f23: (f: (Int, Int) => Int => Int)Int => Int
val f23f = f23(f) // f23f: Int => Int = <function>
f23f(4) // res1: Int = 9
If I place _ at the f23 definition I will get an Error:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
Error:(6, 49) _ must follow method; cannot follow Int => Int
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
What is the reason for this inconsistency?

f is a method, not a function. You can read about some of the differences here.
f12 is a function derived from f via eta-expansion. It is not a partial function. A PartialFunction is a function defined over a limited domain of input values. If, say, f12 was defined only for Int values less than 500, for example, and undefined for input values greater than 500, then it would be a partial function.
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
This fails because f, as defined here, is a function that takes 2 Int values and returns a function that takes an Int and returns an Int. In this situation what is the underscore supposed to be standing in for? f(2,3) is a complete invocation that returns an Int=>Int function. It's a bit like writing 5 + 7 _. It's not clear what the _ is substituting for.
You can, on the other hand, do this: ... = f(2,3)(_). Then it's clear that the returned function is being invoked with a missing, i.e. _, parameter. Which is the same thing as: ... = f(2,3).

This is by design in Scala to prevent developer confusion.
If you tell the compiler the type of f12 explicitly it will work as you expect:
`val f12:Int=>Int = f(1, 2)`
This is explained by the language originator (Martin Odersky):
Why the trailing underscore?
Scala's syntax for partially applied functions highlights a difference in the design trade-offs of Scala and classical functional languages such as Haskell or ML. In these languages, partially applied functions are considered the normal case. Furthermore, these languages have a fairly strict static type system that will usually highlight every error with partial applications that you can make. Scala bears a much closer relation to imperative languages such as Java, where a method that's not applied to all its arguments is considered an error. Furthermore, the object-oriented tradition of subtyping and a universal root type accepts some programs that would be considered erroneous in classical functional languages.
For instance, say you mistook the drop(n: Int) method of List for tail(), and you therefore forgot you need to pass a number to drop. You might write, "println(drop)". Had Scala adopted the classical functional tradition that partially applied functions are OK everywhere, this code would type check. However, you might be surprised to find out that the output printed by this println statement would always be ! What would have happened is that the expression drop would have been treated as a function object. Because println takes objects of any type, this would have compiled OK, but it would have given an unexpected result.
To avoid situations like this, Scala normally requires you to specify function arguments that are left out explicitly, even if the indication is as simple as a `_'. Scala allows you to leave off even the _ only when a function type is expected.

Related

What's the purpose of Currying given other alternatives to return a function in Scala?

I'm currently doing a Scala course and recently I was introduced to different techniques of returning functions.
For example, given this function and method:
val simpleAddFunction = (x: Int, y: Int) => x + y
def simpleAddMethod(x: Int, y: Int) = x + y
I can return another function just doing this:
val add7_v1 = (x: Int) => simpleAddFunction(x, 7)
val add7_v2 = simpleAddFunction(_: Int, 7)
val add7_v3 = (x: Int) => simpleAddMethod(x, 7)
val add7_v4 = simpleAddMethod(_: Int, 7)
All the values add7_x accomplish the same thing, so, whats the purpose of Currying then?
Why I have to write def simpleCurryMethod(x: Int)(y: Int) = x + y if all of the above functions do a similar functionality?
That's it! I'm a newbie in functional programming and I don't know many use cases of Currying apart from saving time by reducing the use of parameters repeatedly. So, if someone could explain me the advantages of currying over the previous examples or in Currying in general I would be very grateful.
That's it, have a nice day!
In Scala 2 there are only four pragmatic reasons for currying METHODS (as far as I can recall, if someone has another valid use case then please let me know).
(and probably the principal reason to use it) to drive type inference.
For example, when you want to accept a function or another kind of generic value whose generic type should be inferred from some plain data. For example:
def applyTwice[A](a: A)(f: A => A): A = f(f(a))
applyTwice(10)(_ + 1) // Here the compiler is able to infer that f is Int => Int
In the above example, if I wouldn't have curried the function then I would need to have done something like: applyTwice(10, (x: Int) => x + 1) to call the function.
Which is redundant and looks worse (IMHO).
Note: In Scala 3 type inference is improved thus this reason is not longer valid there.
(and probably the main reason now in Scala 3) for the UX of callers.
For example, if you expect an argument to be a function or a block it is usually better as a single argument in its own (and last) parameter list so it looks nice in usage. For example:
def iterN(n: Int)(body: => Unit): Unit =
if (n > 0) {
body
iterN(n - 1)(body)
}
iterN(3) {
println("Hello")
// more code
println("World")
}
Again, if I wouldn't have curried the previous method the usage would have been like this:
iterN(3, {
println("Hello")
// more code
println("World")
})
Which doesn't look that nice :)
(in my experience weird but valid) when you know that majority of users will call it partially to return a function.
Because val baz = foo(bar) _ looks better than val baz = foo(bar, _) and with the first one, you sometimes don't the the underscore like: data.map(foo(bar))
Note: Disclaimer, I personally think that if this is the case, is better to just return a function right away instead of currying.
Edit
Thanks to #jwvh for pointing out this fourth use case.
(useful when using path-dependant types) when you need to refer to previous parameters. For example:
trait Foo {
type I
def bar(i: I): Baz
}
def run(foo: Foo)(i: foo.I): Baz =
foo.bar(i)

Why I can't apply just an underscore to first parameter in Scala?

I don't know why pattern d is bad in this list below.
Why need expicit type declaration?
def adder1(m:Int,n:Int) = m + n
val a = adder1(2,_) //OK
val b = adder1(_,2) //OK
def adder2(m:Int)(n:Int) = m + n
val c = adder2(2)(_) //OK
val d = adder2(_)(2) //NG:missing parameter type
val e = adder2(_:Int)(2) //OK
I just want to know the reason pattern d needs parameter type.
Very welcome just showing citation language spec.
So I believe this comes from the concept of Partial Application.
Intuitively, partial function application says "if you fix the first arguments of the function, you get a function of the remaining arguments"
...
Scala implements optional partial application with placeholder, e.g. def add(x: Int, y: Int) = {x+y}; add(1, _: Int) returns an incrementing function. Scala also support multiple parameter lists as currying, e.g. def add(x: Int)(y: Int) = {x+y}; add(1) _.
Lets take a look at adder2
From the REPL:
scala> def adder2(m:Int)(n:Int) = m + n
def adder2(m: Int)(n: Int): Int
Lets get a value to represent this:
scala> val adder2Value = adder2
^
error: missing argument list for method adder2
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `adder2 _` or `adder2(_)(_)` instead of `adder2`.
Ok, let's try:
val adder2Value = adder2 _
val adder2Value: Int => (Int => Int) = $Lambda$1382/0x0000000840703840#4b66a923
Ahha!
In English: "A function that takes an Int and returns a function that takes an Int and returns an Int"
How can we bind the second argument using this signature? How can we access the inner function unless we first have gone through the outer one?
As far as I know, this is not possible to do using this signature, unless you explicitly define the type of your first argument.
(But what about adder2(_)(_)?)
scala> adder2(_)(_)
^
error: missing parameter type for expanded function ((<x$1: error>, x$2) => adder2(x$1)(x$2))
^
error: missing parameter type for expanded function ((<x$1: error>, <x$2: error>) => adder2(x$1)(x$2))
(Maybe this hints at our solution?)
Notice what happens if we explicitly define both arguments:
val adder2Value2= adder2Value (_:Int) (_:Int)
val adder2Value2: (Int, Int) => Int = $Lambda$1394/0x000000084070d840#32f7d983
This is much more manageable, we can now fix either argument, and get a simplified partial function:
scala> val adder2FirstArg = adder2Value (_:Int) (10)
val adder2FirstArg: Int => Int = $Lambda$1395/0x000000084070d040#47f5ddf4
scala> val adder2SecondArg = adder2Value (5) (_:Int)
val adder2SecondArg: Int => Int = $Lambda$1396/0x000000084070c840#21ed7ce
So what's really going on here?
When you bind an argument to a value, you have explicitly expressed the type (maybe it's inferred, but it's definitely that type, in this case, Ints). It's sugar so we don't need to write it. But under the hood, these are composed functions, and how they are composed is very important. To be able to match and simplify the function signature, the compiler requires us to provide this information in an outside-in manner. Otherwise, we need to give it some help to get there.
EDIT:
I think that this question serves as more of a Scala language spec. puzzle exercise, however. I can't think of any good reason, from a design perspective, for which you would need to implement a curried function in such a way that you cannot order the parameters such that the last parameters are the ones being inferred.

Scala anonymous function syntax using partial application?

I'm learning specs2 testing framework by following some of its examples.
I've noticed the following anonymous function syntax is recurring:
val upper = (_: String).toUpperCase
which is equivalent to more conventional / usual
val upper = (s: String) => s.toUpperCase
Although the syntax is simple and elegant, yet it's not very familiar (easy).
Can someone step me through how the first syntax works / derives? I'm pretty sure that it has to do with some sort of partial application but cannot reason fully.
Also is the syntax used frequently in Scala? (I'm still learning the ropes here :] )
Edit::
I've found the recurring pattern to use such syntax is with ad-hoc polymorphism (simply, overloaded methods / functions) where argument type of the passed function determines what function is dispatched.
For example,
def f(g: Int => String): String = g(10)
def f(g: String => String): String = g("hello")
f((_: Int).toString + " beers") // 10 beers
f((_: String) + " world") // hello world
This kind of pattern is recurring in libraries like ScalaCheck.
The syntax indicates the compiler you're creating a function with a parameter of type String, which is inserted where the _ is used, according to parameter order. If you had:
val f = (_:String).length + (_:Int)
it would create a function (String, Int) => Int, where each _ marks where the parameter is being used. The order is important! They must be used in the same order you want the function's parameters to be
If the types are already defined when declaring the val, you can omit them in the function body:
val f: (String, Int) => Int = _.length + _

Difference between currying and higher-order functions

Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:
1. Higher-Order Function
def withPrintWriter(file: File, op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
2. Currying function
def withPrintWriter(file: File)(op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
What is the difference between them? Can we always achieve the same result in both ways?
The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.
A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.
Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:
def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
Higher order functions are functions that either take functions as parameter or return functions or both.
def f(g: Int => Int) = g(_: Int) + 23
scala> f(_ + 45)
res1: Int => Int = <function1>
scala> res1(4)
res2: Int = 72
This is a higher order function, it takes a function as parameter and returns another function. As you can see, higher order functions are a pre-requisite for currying. The curry function looks like this:
def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)
scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>
scala> res3(3)
res4: Int => Int = <function1>
scala> res4(3)
res5: Int = 6
So to answer your question: They are two different concepts, where the one (higher order functions) is the pre-requisit for the other (currying).
Semantically, there is one difference I can think of between a curried and a not curried function. With the non-curried version, when you call withPrintWriter, that's a single method call. With the curried version, it's actually going to be two method calls. Think of it like this:
withPrintWriter.apply(file).apply(op)
Other than that, I think a lot of people use currying in this kind of situation for style. Using currying here makes this look more like a language feature then just a custom function call because you can use it like this:
withPrintWriter(file){ op =>
...
}
Using it in that way is trying to emulate some sore of control structure from the language itself, but again, this is only really a style thing and it does come with the overhead of an additional method call.
You can use the non-curried version in almost the same way, but it's not as clean looking:
withPrintWriter(file, { op =>
...
})
EDIT
#drexin makes a good point in his answer that it's worth mentioning here for me. When you think of the signature of the curried version of the method, it's really:
Function1[File, Function1[PrintWriter, Unit]]
They are mostly the same, but there is a difference with regard to type inference. Scala is not able to infer types between arguments of a single method invocation, but it is able to infer types for multiple argument lists.
Consider:
def foo1[T](x : T, y : T => T) = y(x)
def foo2[T](x : T)(y : T => T) = y(x)
foo1(1, t => t + 1) //does not compile with 'missing parameter type'
foo2(1)(t => t + 1) //compiles
You can see some additional information in this answer : Multiple parameter closure argument type not inferred
Strictly speaking, the example you gave is not really curried, it just has multiple argument lists. It just happens that multiple argument list Scala functions look a lot like curried functions in many situations. However, when you call a multiple argument list function but don't fill in one or more argument lists, it's really an example of partial application, not currying. Calling a multiple argument list with all its arguments is just one function call, not one per argument list.
There are two use cases where multiple argument list functions are helpful. The first is the case of implicit parameters, since all implicit parameters have to be in their own argument list separate from any explicit parameters. The second use case is functions that accept other functions as parameters, since if a parameter that is a function is in its own argument list, you can leave off the parentheses and just use braces, making the function call look like some sort of control structure.
Other than that, the difference is purely cosmetic.

Why does Scala require partial application of curried functions when assigning to a val?

In Scala, why is it that a curried function can easily be passed directly to other functions, but when assigning it to a val one needs to also partially apply it with _? For example, given the two functions:
def curried(a: Int)(b: Int) = a + b
def test(a: Int, f: Int => Int) = f(a)
I can easily pass curried to test with:
test(5, curried(5))
and everything is happy. However if I simply call curried(5) I get an error:
scala> curried(5)
<console>:9: error: missing arguments for method curried;
follow this method with `_' if you want to treat it as a partially applied function
curried(5)
If I change the call to include type information however, it works:
val 'curried: Int => Int = curried(5)
Can anyone explain the rational behind the inconsistency, surely the Scala compiler can infer that the function is Int => Int given the type definition on the original method?
The problem is not inferring the type, the problem is inferring your intent. Did you make a mistake, or did you intentionally curry the function?
Alas, the trailing underscore syntax is the formal syntax, and omitting it is syntactical sugar.
The underscore isn't always needed. From http://docs.scala-lang.org/cheatsheets/
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd
currying, obvious syntax.
def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd
currying, obvious syntax
def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd
currying, sugar syntax. but then:
val normer = zscore(7, 0.4) _
need trailing underscore to get the partial, only for the sugar version.