Related
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)
In this comment, #Ben suggested that call by name is equivalent to call by value where values are zero-argument functions. If I understood correctly,
def callByName(x: => Int) = {
// some code
}
callByName(something())
is equivalent to
def callByValue(x: () => Int) = {
// same code as above, but all occurrences of x replaced with x()
}
callByValue(()=>something())
(Edit: I fixed mistake in signature as pointed out by #MichaelZajac, #LukaJacobowitz: originally, it said callByValue(x: Int).)
In other words, the whole "call by name" concept is just syntactic sugar: everything it does can be achieved (with a few extra keystrokes) using "call by value". If true, it makes it very easy to understand call by name; in fact, I've used this technique in python (python has first-class functions).
However, further down in the comments, the discussion became somewhat more confusing, and I was left with the feeling that it's not quite so simple.
So is there something more substantive to "call by name"? Or is it just an automatic creation of zero-argument functions by the compiler?
I'm assuming you meant your callByValue function to take a () => Int instead of just an Int as otherwise it wouldn't make a lot of sense.
It's pretty much exactly what you think. The compiler generates a Function0 instance. You can see this pretty nicely when you decompile Scala code with Javap.
Another thing of note is, that the generated Function0 will be reevaluated every time you use the by-name parameter inside your function, so if you only want it to be computed once you'll want to do something like this:
def callByName(x: => Int) = {
val a = x
// do something with a here
}
Here is some more information on the whole concept.
Also you can see how Scala compiles by-name parameters quite neatly in this question:
def getX[T <: X](constr: ⇒ T): Unit = {
constr
}
decompiled in Java is equivalent to:
public <T extends X> void getX(Function0<T> constr) {
constr.apply();
}
Yes, but your example isn't quite right. The signature of callByValue, as written in your question, will evaluate x before callByValue is invoked.
The following would be roughly equivalent to a call-by-name:
def callByValue(x: () => Int) = {
// same code as above, but all occurrences of x replaced with x()
}
The distinction is important, because your version of callByValue would only accept Ints, not functions that return Ints. It also wouldn't compile if you followed the procedure of replacing x with x().
But yes, a call-by-name parameter of => A is roughly equivalent to () => A, except that the former is simply more convenient to use. I say roughly because they are different types, and their applications are slightly different. You can specify () => A to be the type of something, but not => A. And of course with x: () => A, you must manually call x() instead of x.
What is the reason behind the design decision in Scala that monads do not have a return/unit function in contrast to Haskell where each monad has a return function that puts a value into a standard monadic context for the given monad?
For example why List, Option, Set etc... do not have a return/unit functions defined in the standard library as shown in the slides below?
I am asking this because in the reactive Coursera course Martin Odersky explicitly mentioned this fact, as can be seen below in the slides, but did not explain why Scala does not have them even though unit/return is an essential property of a monad.
As Ørjan Johansen said, Scala does not support method dispatching on return type. Scala object system is built over JVM one, and JVM invokevirtual instruction, which is the main tool for dynamic polymorphism, dispatches the call based on type of this object.
As a side note, dispatching is a process of selecting concrete method to call. In Scala/Java all methods are virtual, that is, the actual method which is called depends on actual type of the object.
class A { def hello() = println("hello method in A") }
class B extends A { override def hello() = println("hello method in B") }
val x: A = new A
x.hello() // prints "hello method in A"
val y: A = new B
y.hello() // prints "hello method in B"
Here, even if y variable is of type A, hello method from B is called, because JVM "sees" that the actual type of the object in y is B and invokes appropriate method.
However, JVM only takes the type of the variable on which the method is called into account. It is impossible, for example, to call different methods based on runtime type of arguments without explicit checks. For example:
class A {
def hello(x: Number) = println(s"Number: $x")
def hello(y: Int) = println(s"Integer: $y")
}
val a = new A
val n: Number = 10: Int
a.hello(n) // prints "Number: 10"
Here we have two methods with the same name, but with different parameter type. And even if ns actual type is Int, hello(Number) version is called - it is resolved statically based on n static variable type (this feature, static resolution based on argument types, is called overloading). Hence, there is no dynamic dispatch on method arguments. Some languages support dispatching on method arguments too, for example, Common Lisp's CLOS or Clojure's multimethods work like that.
Haskell has advanced type system (it is comparable to Scala's and in fact they both originate in System F, but Scala type system supports subtyping which makes type inference much more difficult) which allows global type inference, at least, without certain extensions enabled. Haskell also has a concept of type classes, which is its tool for dynamic polymorphism. Type classes can be loosely thought of as interfaces without inheritance but with dispatch on parameter and return value types. For example, this is a valid type class:
class Read a where
read :: String -> a
instance Read Integer where
read s = -- parse a string into an integer
instance Read Double where
read s = -- parse a string into a double
Then, depending on the context where method is called, read function for Integer or Double can be called:
x :: Integer
x = read "12345" // read for Integer is called
y :: Double
y = read "12345.0" // read for Double is called
This is a very powerful technique which has no correspondence in bare JVM object system, so Scala object system does not support it too. Also the lack of full-scale type inference would make this feature somewhat cumbersome to use. So, Scala standard library does not have return/unit method anywhere - it is impossible to express it using regular object system, there is simply no place where such a method could be defined. Consequently, monad concept in Scala is implicit and conventional - everything with appropriate flatMap method can be considered a monad, and everything with the right methods can be used in for construction. This is much like duck typing.
However, Scala type system together with its implicits mechanism is powerful enough to express full-featured type classes, and, by extension, generic monads in formal way, though due to difficulties in full type inference it may require adding more type annotations than in Haskell.
This is definition of monad type class in Scala:
trait Monad[M[_]] {
def unit[A](a: A): M[A]
def bind[A, B](ma: M[A])(f: A => M[B]): M[B]
}
And this is its implementation for Option:
implicit object OptionMonad extends Monad[Option] {
def unit[A](a: A) = Some(a)
def bind[A, B](ma: Option[A])(f: A => Option[B]): Option[B] =
ma.flatMap(f)
}
Then this can be used in generic way like this:
// note M[_]: Monad context bound
// this is a port of Haskell's filterM found here:
// http://hackage.haskell.org/package/base-4.7.0.1/docs/src/Control-Monad.html#filterM
def filterM[M[_]: Monad, A](as: Seq[A])(f: A => M[Boolean]): M[Seq[A]] = {
val m = implicitly[Monad[M]]
as match {
case x +: xs =>
m.bind(f(x)) { flg =>
m.bind(filterM(xs)(f)) { ys =>
m.unit(if (flg) x +: ys else ys)
}
}
case _ => m.unit(Seq.empty[A])
}
}
// using it
def run(s: Seq[Int]) = {
import whatever.OptionMonad // bring type class instance into scope
// leave all even numbers in the list, but fail if the list contains 13
filterM[Option, Int](s) { a =>
if (a == 13) None
else if (a % 2 == 0) Some(true)
else Some(false)
}
}
run(1 to 16) // returns None
run(16 to 32) // returns Some(List(16, 18, 20, 22, 24, 26, 28, 30, 32))
Here filterM is written generically, for any instance of Monad type class. Because OptionMonad implicit object is present at filterM call site, it will be passed to filterM implicitly, and it will be able to make use of its methods.
You can see from above that type classes allow to emulate dispatching on return type even in Scala. In fact, this is exactly what Haskell does under the covers - both Scala and Haskell are passing a dictionary of methods implementing some type class, though in Scala it is somewhat more explicit because these "dictionaries" are first-class objects there and can be imported on demand or even passed explicitly, so it is not really a proper dispatching as it is not that embedded.
If you need this amount of genericity, you can use Scalaz library which contains a lot of type classes (including monad) and their instances for some common types, including Option.
I don't think you're really saying that Scala's monads don't have a unit function - it's rather just that the name of the unit function can vary. That's what seems to be shown in the second slide's examples.
As for why that is so, I think it's just because Scala runs on the JVM, and those function have to be implemented as JVM methods - which are uniquely identified by:
the class they belong to;
their name;
their parameters types.
But they are not identified by their return type. Since the parameter type generally won't differentiate the various unit functions (it's usually just a generic type), you need different names for them.
In practice, they will often be implemented as the apply(x) method on the companion object of the monad class. For example, for the class List, the unit function is the apply(x) method on the object List. By convention, List.apply(x) can be called as List(x) too, which is more common/idiomatic.
So I guess that Scala at least has a naming convention for the unit function, though it doesn't have a unique name for it :
// Some monad :
class M[T] {
def flatMap[U](f: T => M[U]): M[U] = ???
}
// Companion object :
object M {
def apply(x: T): M[T] = ??? // Unit function
}
// Usage of the unit function :
val x = ???
val m = M(x)
Caveat: I'm still learning Haskell and I'm sort of making up this answer as I go.
First, what you already know - that Haskell's do notation desugars to bind:
Borrowing this example from Wikipedia:
add mx my = do
x <- mx
y <- my
return (x + y)
add mx my =
mx >>= (\x ->
my >>= (\y ->
return (x + y)))
Scala's analogue to do is the for-yield expression. It similarly desugars each step to flatMap (its equivalent of bind).
There's a difference, though: The last <- in a for-yield desugars to map, not to flatMap.
def add(mx: Option[Int], my: Option[Int]) =
for {
x <- mx
y <- my
} yield x + y
def add(mx: Option[Int], my: Option[Int]) =
mx.flatMap(x =>
my.map(y =>
x + y))
So because you don't have the "flattening" on the last step, the expression value already has the monad type, so there's no need to "re-wrap" it with something comparable to return.
Actually there is a return function in scala. It is just hard to find.
Scala slightly differs from Haskell in many aspects. Most of that differences are direct consequences of JVM limitations. JVM can not dispatch methods basing on its return type. So Scala introduced type class polymorphism based on implicit evidence to fix this inconvenience.
It is even used in scala standard collections. You may notice numerous usage of CanBuildFrom and CanBuild implicits used in the scala collection api. See scala.collection.immutable.List for example.
Every time you want to build custom collection you should write realization for this implicits. There are not so many guides for writing one though. I recommend you this guide. It shows why CanBuildFrom is so important for collections and how it is used. In fact that is just another form of the return function and anyone familiar with Haskell monads would understand it's importance clearly.
So you may use custom collection as example monads and write other monads basing on provided tutorial.
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.
I understand the difference between zero-parameter and parameterless methods, but what I don't really understand is the language design choice that made parameterless methods necessary.
Disadvantages I can think of:
It's confusing. Every week or two there are questions here or on the Scala mailing list about it.
It's complicated; we also have to distinguish between () => X and => X.
It's ambiguous: does x.toFoo(y) mean what it says, or x.toFoo.apply(y)? (Answer: it depends on what overloads there are x's toFoo method and the overloads on Foo's apply method, but if there's a clash you don't see an error until you try to call it.)
It messes up operator style method calling syntax: there is no symbol to use in place of the arguments, when chaining methods, or at the end to avoid semicolon interference. With zero-arg methods you can use the empty parameter list ().
Currently, you can't have both defined in a class: you get an error saying the method is already defined. They also both convert to a Function0.
Why not just make methods def foo and def foo() exactly the same thing, and allow them to be called with or without parentheses? What are the upsides of how it is?
Currying, That's Why
Daniel did a great job at explaining why parameterless methods are necessary. I'll explain why they are regarded distinctly from zero-parameter methods.
Many people view the distinction between parameterless and zero-parameter functions as some vague form of syntactic sugar. In truth it is purely an artifact of how Scala supports currying (for completeness, see below for a more thorough explanation of what currying is, and why we all like it so much).
Formally, a function may have zero or more parameter lists, with zero or more parameters each.
This means the following are valid: def a, def b(), but also the contrived def c()() and def d(x: Int)()()(y: Int) etc...
A function def foo = ??? has zero parameter lists. A function def bar() = ??? has precisely one parameter list, with zero parameters. Introducing additional rules that conflate the two forms would have undermined currying as a consistent language feature: def a would be equivalent in form to def b() and def c()() both; def d(x: Int)()()(y: Int) would be equivalent to def e()(x: Int)(y: Int)()().
One case where currying is irrelevant is when dealing with Java interop. Java does not support currying, so there's no problem with introducing syntactic sugar for zero-parameter methods like "test".length() (which directly invokes java.lang.String#length()) to also be invoked as "test".length.
A quick explanation of currying
Scala supports a language feature called 'currying', named after mathematician Haskell Curry.
Currying allows you to define functions with several parameter lists, e.g.:
def add(a: Int)(b: Int): Int = a + b
add(2)(3) // 5
This is useful, because you can now define inc in terms of a partial application of add:
def inc: Int => Int = add(1)
inc(2) // 3
Currying is most often seen as a way of introducing control structures via libraries, e.g.:
def repeat(n: Int)(thunk: => Any): Unit = (1 to n) foreach { _ => thunk }
repeat(2) {
println("Hello, world")
}
// Hello, world
// Hello, world
As a recap, see how repeat opens up another opportunity to use currying:
def twice: (=> Any) => Unit = repeat(2)
twice {
println("Hello, world")
}
// ... you get the picture :-)
One nice thing about an issue coming up periodically on the ML is that there are periodic answers.
Who can resist a thread called "What is wrong with us?"
https://groups.google.com/forum/#!topic/scala-debate/h2Rej7LlB2A
From: martin odersky Date: Fri, Mar 2, 2012 at
12:13 PM Subject: Re: [scala-debate] what is wrong with us...
What some people think is "wrong with us" is that we are trying bend
over backwards to make Java idioms work smoothly in Scala. The
principaled thing would have been to say def length() and def length
are different, and, sorry, String is a Java class so you have to write
s.length(), not s.length. We work really hard to paper over it by
admitting automatic conversions from s.length to s.length(). That's
problematic as it is. Generalizing that so that the two are identified
in the type system would be a sure way to doom. How then do you
disambiguate:
type Action = () => () def foo: Action
Is then foo of type Action or ()? What about foo()?
Martin
My favorite bit of paulp fiction from that thread:
On Fri, Mar 2, 2012 at 10:15 AM, Rex Kerr <ich...#gmail.com> wrote:
>This would leave you unable to distinguish between the two with
>structural types, but how often is the case when you desperately
>want to distinguish the two compared to the case where distinguishing
>between the two is a hassle?
/** Note to maintenance programmer: It is important that this method be
* callable by classes which have a 'def foo(): Int' but not by classes which
* merely have a 'def foo: Int'. The correctness of this application depends
* on maintaining this distinction.
*
* Additional note to maintenance programmer: I have moved to zambia.
* There is no forwarding address. You will never find me.
*/
def actOnFoo(...)
So the underlying motivation for the feature is to generate this sort of ML thread.
One more bit of googlology:
On Thu, Apr 1, 2010 at 8:04 PM, Rex Kerr <[hidden email]> wrote: On
Thu, Apr 1, 2010 at 1:00 PM, richard emberson <[hidden email]> wrote:
I assume "def getName: String" is the same as "def getName(): String"
No, actually, they are not. Even though they both call a method
without parameters, one is a "method with zero parameter lists" while
the other is a "method with one empty parameter list". If you want to
be even more perplexed, try def getName()(): String (and create a
class with that signature)!
Scala represents parameters as a list of lists, not just a list, and
List() != List(List())
It's kind of a quirky annoyance, especially since there are so few
distinctions between the two otherwise, and since both can be
automatically turned into the function signature () => String.
True. In fact, any conflation between parameterless methods and
methods with empty parameter lists is entirely due to Java interop.
They should be different but then dealing with Java methods would be
just too painful. Can you imagine having to write str.length() each
time you take the length of a string?
Cheers
First off, () => X and => X has absolutely nothing to do with parameterless methods.
Now, it looks pretty silly to write something like this:
var x() = 5
val y() = 2
x() = x() + y()
Now, if you don't follow what the above has to do with parameterless methods, then you should look up uniform access principle. All of the above are method declarations, and all of them can be replaced by def. That is, assuming you remove their parenthesis.
Besides the convention fact mentioned (side-effect versus non-side-effect), it helps with several cases:
Usefulness of having empty-paren
// short apply syntax
object A {
def apply() = 33
}
object B {
def apply = 33
}
A() // works
B() // does not work
// using in place of a curried function
object C {
def m()() = ()
}
val f: () => () => Unit = C.m
Usefulness of having no-paren
// val <=> def, var <=> two related defs
trait T { def a: Int; def a_=(v: Int): Unit }
trait U { def a(): Int; def a_=(v: Int): Unit }
def tt(t: T): Unit = t.a += 1 // works
def tu(u: U): Unit = u.a += 1 // does not work
// avoiding clutter with apply the other way round
object D {
def a = Vector(1, 2, 3)
def b() = Vector(1, 2, 3)
}
D.a(0) // works
D.b(0) // does not work
// object can stand for no-paren method
trait E
trait F { def f: E }
trait G { def f(): E }
object H extends F {
object f extends E // works
}
object I extends G {
object f extends E // does not work
}
Thus in terms of regularity of the language, it makes sense to have the distinction (especially for the last shown case).
I would say both are possible because you can access mutable state with a parameterless method:
class X(private var x: Int) {
def inc() { x += 1 }
def value = x
}
The method value does not have side effects (it only accesses mutable state). This behavior is explicitly mentioned in Programming in Scala:
Such parameterless methods are quite common in Scala. By contrast, methods defined with empty parentheses, such as def height(): Int, are called empty-paren methods. The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state).
This convention supports the uniform access principle [...]
To summarize, it is encouraged style in Scala to define methods that take no parameters and have no side effects as parameterless methods, i.e., leaving off the empty parentheses. On the other hand, you should never define a method that has side-effects without parentheses, because then invocations of that method would look like a field selection.