This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Why use currying?

16 replies
Outsider ..
Joined: 2010-10-09,
User offline. Last seen 42 years 45 weeks ago.
Hi
I'm studying about currying.But I don't know what benefit of currying.
when do I use currying?
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Why use currying?

Am 09.10.2010 09:48, schrieb Outsider ..:
> Hi
>
> I'm studying about currying.
> But I don't know what benefit of currying.
>
> when do I use currying?

*making up an example*

class MagicLogger
def logCurried(a:String)(b:String) = {
println(a+b)
}

class SomeLogger {
val logger = new MagicLogger
def getLogger(withPrefix:String) {
logger.logCurried(withPrefix)
}
}

usage:
val somelogger = new SomeLogger
...
val curriedMagicLoggingFunction = somelogger.getLogger("myprefix")
...
curriedMagicLoggingFunction("my message")

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Why use currying?

basically, you can use currying if you want to plug a function together
at different places

Am 09.10.2010 10:33, schrieb HamsterofDeath:
> Am 09.10.2010 09:48, schrieb Outsider ..:
>> Hi
>>
>> I'm studying about currying.
>> But I don't know what benefit of currying.
>>
>> when do I use currying?
> *making up an example*
>
> class MagicLogger
> def logCurried(a:String)(b:String) = {
> println(a+b)
> }
>
> class SomeLogger {
> val logger = new MagicLogger
> def getLogger(withPrefix:String) {
> logger.logCurried(withPrefix)
> }
> }
>
> usage:
> val somelogger = new SomeLogger
> ...
> val curriedMagicLoggingFunction = somelogger.getLogger("myprefix")
> ...
> curriedMagicLoggingFunction("my message")
>
>

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Why use currying?

Arguments passed one parameter section can be used to infer the types
of a formal parameter in a subsequent parameter section:

http://gist.github.com/618151

On Sat, Oct 9, 2010 at 9:48 AM, Outsider .. wrote:
> Hi
> I'm studying about currying.
> But I don't know what benefit of currying.
> when do I use currying?

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Why use currying?

imo, it's a disadvantage that you need parameter lists for this
Am 09.10.2010 14:38, schrieb Jason Zaugg:
> Arguments passed one parameter section can be used to infer the types
> of a formal parameter in a subsequent parameter section:
>
> http://gist.github.com/618151
>
> On Sat, Oct 9, 2010 at 9:48 AM, Outsider .. wrote:
>> Hi
>> I'm studying about currying.
>> But I don't know what benefit of currying.
>> when do I use currying?

imaier
Joined: 2008-07-01,
User offline. Last seen 23 weeks 2 days ago.
Re: Why use currying?

On 10/9/10 2:49 PM, HamsterofDeath wrote:
> imo, it's a disadvantage that you need parameter lists for this

How else would you do it?

Here are a few other considerations for or against currying in Scala.

1) As Jason already mentioned, type inference is one. Another related
thing is overloading, which is based on the first argument list only:

You can do

class A {
def f(x: Int, y: Int) {}
def f(x: Int, s: String) {}
}

but not

class A {
def f(x: Int)(y: Int) {}
def f(x: Int)(s: String) {}
}

Well, actually, looks like I hit a bug:

scala> class A {
| def f(x: Int)(y: Int) {}
| def f(x: Int)(s: String) {}
| }
defined class A

scala> (new A).f(0)
:7: error: ambiguous reference to overloaded definition,
both method f in class A of type (x: Int)(s: String)Unit
and method f in class A of type (x: Int)(y: Int)Unit
match argument types (Int)
(new A).f(0)
^

Same for (new A).f(0)(1) and (new A).f(0)("")

2) Default arguments and dependent method types can only use arguments
from previous argument lists (at least for now).

You can do:

def f(x: Int)(y: Int = g(x))

but not

def f(x: Int, y: Int = g(x))

Similarily for dependent method types.

3) Convenient closure syntax (especially useful for DSLs):

xs.foldLeft(x) { (a,b) => f(a,b) }

instead of

xs.foldLeft(x, { (a,b) => f(a,b) })

Some of these considerations sometimes work against each other though.
The nice dangling code block syntax can be at odds with type inference.
For example:

scala> def f[A](init: A)(iter: Int=>A) {}
f: [A](init: A)(iter: (Int) => A)Unit

scala> f(Nil) { i => List(i) }

:7: error: type mismatch;
found : List[Int]
required: object Nil
f(Nil) { i => List(i) }
^

scala> def g[A](init: A, iter: Int=>A) {}
g: [A](init: A,iter: (Int) => A)Unit

scala> g(Nil, { i => List(i) })

Ingo

> Am 09.10.2010 14:38, schrieb Jason Zaugg:
>> Arguments passed one parameter section can be used to infer the types
>> of a formal parameter in a subsequent parameter section:
>>
>> http://gist.github.com/618151
>>
>> On Sat, Oct 9, 2010 at 9:48 AM, Outsider .. wrote:
>>> Hi
>>> I'm studying about currying.
>>> But I don't know what benefit of currying.
>>> when do I use currying?
>
>

bmaso
Joined: 2009-10-04,
User offline. Last seen 2 years 40 weeks ago.
Re: Why use currying?

On Saturday, October 9, 2010, Ingo Maier wrote:
> On 10/9/10 2:49 PM, HamsterofDeath wrote:
>
>  imo, it's a disadvantage that you need parameter lists for this
>
>
> How else would you do it?
>
> Here are a few other considerations for or against currying in Scala.
>
> 1) As Jason already mentioned, type inference is one. Another related thing is overloading, which is based on the first argument list only:
>
> You can do
>
> class A {
>  def f(x: Int, y: Int) {}
>  def f(x: Int, s: String) {}
> }
>
> but not
>
> class A {
>  def f(x: Int)(y: Int) {}
>  def f(x: Int)(s: String) {}
> }
>
> Well, actually, looks like I hit a bug:
>
> scala> class A {
>     |   def f(x: Int)(y: Int) {}
>     |   def f(x: Int)(s: String) {}
>     | }
> defined class A
>
> scala> (new A).f(0)
> :7: error: ambiguous reference to overloaded definition,
> both method f in class A of type (x: Int)(s: String)Unit
> and  method f in class A of type (x: Int)(y: Int)Unit
> match argument types (Int)
>       (new A).f(0)
>               ^
>
> Same for (new A).f(0)(1) and (new A).f(0)("")

Not actually a bug -- been documented on this list before. Recall that

def fun(param1:T1)(param2:T2) = body

Is sugar for

def fun(param1:T1) = {
(param2:T2) => { body }
}

So if the number and type of the first param list of two functions in
the same class are the same, you have ambiguous method overloading.

Brian Maso

>
>
> 2) Default arguments and dependent method types can only use arguments from previous argument lists (at least for now).
>
> You can do:
>
> def f(x: Int)(y: Int = g(x))
>
> but not
>
> def f(x: Int, y: Int = g(x))
>
> Similarily for dependent method types.
>
> 3) Convenient closure syntax (especially useful for DSLs):
>
> xs.foldLeft(x) { (a,b) => f(a,b) }
>
> instead of
>
> xs.foldLeft(x, { (a,b) => f(a,b) })
>
>
> Some of these considerations sometimes work against each other though. The nice dangling code block syntax can be at odds with type inference. For example:
>
> scala> def f[A](init: A)(iter: Int=>A) {}
> f: [A](init: A)(iter: (Int) => A)Unit
>
> scala> f(Nil) { i => List(i) }
> :7: error: type mismatch;
>  found   : List[Int]
>  required: object Nil
>       f(Nil) { i => List(i) }
>                         ^
>
> scala> def g[A](init: A, iter: Int=>A) {}
> g: [A](init: A,iter: (Int) => A)Unit
>
> scala> g(Nil, { i => List(i) })
>
> Ingo
>
>
> Am 09.10.2010 14:38, schrieb Jason Zaugg:
>
> Arguments passed one parameter section can be used to infer the types
> of a formal parameter in a subsequent parameter section:
>
> http://gist.github.com/618151
>
> On Sat, Oct 9, 2010 at 9:48 AM, Outsider ..  wrote:
>
> Hi
> I'm studying about currying.
> But I don't know what benefit of currying.
> when do I use currying?
>
>
>
>
>
>

Outsider ..
Joined: 2010-10-09,
User offline. Last seen 42 years 45 weeks ago.
Re: Why use currying?
Thank you!!It's really helpful.

On Sat, Oct 9, 2010 at 10:58 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
On Saturday, October 9, 2010, Ingo Maier <ingo.maier@epfl.ch> wrote:
> On 10/9/10 2:49 PM, HamsterofDeath wrote:
>
>   imo, it's a disadvantage that you need parameter lists for this
>
>
> How else would you do it?
>
> Here are a few other considerations for or against currying in Scala.
>
> 1) As Jason already mentioned, type inference is one. Another related thing is overloading, which is based on the first argument list only:
>
> You can do
>
> class A {
>   def f(x: Int, y: Int) {}
>   def f(x: Int, s: String) {}
> }
>
> but not
>
> class A {
>   def f(x: Int)(y: Int) {}
>   def f(x: Int)(s: String) {}
> }
>
> Well, actually, looks like I hit a bug:
>
> scala> class A {
>      |   def f(x: Int)(y: Int) {}
>      |   def f(x: Int)(s: String) {}
>      | }
> defined class A
>
> scala> (new A).f(0)
> <console>:7: error: ambiguous reference to overloaded definition,
> both method f in class A of type (x: Int)(s: String)Unit
> and  method f in class A of type (x: Int)(y: Int)Unit
> match argument types (Int)
>        (new A).f(0)
>                ^
>
> Same for (new A).f(0)(1) and (new A).f(0)("")

Not actually a bug -- been documented on this list before. Recall that

def fun(param1:T1)(param2:T2) = body

Is sugar for

def fun(param1:T1) = {
 (param2:T2) => { body }
}

So if the number and type of the first param list of two functions in
the same class are the same, you have ambiguous method overloading.

Brian Maso


>
>
> 2) Default arguments and dependent method types can only use arguments from previous argument lists (at least for now).
>
> You can do:
>
> def f(x: Int)(y: Int = g(x))
>
> but not
>
> def f(x: Int, y: Int = g(x))
>
> Similarily for dependent method types.
>
> 3) Convenient closure syntax (especially useful for DSLs):
>
> xs.foldLeft(x) { (a,b) => f(a,b) }
>
> instead of
>
> xs.foldLeft(x, { (a,b) => f(a,b) })
>
>
> Some of these considerations sometimes work against each other though. The nice dangling code block syntax can be at odds with type inference. For example:
>
> scala> def f[A](init: A)(iter: Int=>A) {}
> f: [A](init: A)(iter: (Int) => A)Unit
>
> scala> f(Nil) { i => List(i) }
> <console>:7: error: type mismatch;
>  found   : List[Int]
>  required: object Nil
>        f(Nil) { i => List(i) }
>                          ^
>
> scala> def g[A](init: A, iter: Int=>A) {}
> g: [A](init: A,iter: (Int) => A)Unit
>
> scala> g(Nil, { i => List(i) })
>
> Ingo
>
>
> Am 09.10.2010 14:38, schrieb Jason Zaugg:
>
> Arguments passed one parameter section can be used to infer the types
> of a formal parameter in a subsequent parameter section:
>
> http://gist.github.com/618151
>
> On Sat, Oct 9, 2010 at 9:48 AM, Outsider ..<outsideris@gmail.com>  wrote:
>
> Hi
> I'm studying about currying.
> But I don't know what benefit of currying.
> when do I use currying?
>
>
>
>
>
>

--
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: Why use currying?

On Saturday October 9 2010, Outsider .. wrote:
> Hi
>
> I'm studying about currying.
> But I don't know what benefit of currying.
>
> when do I use currying?

How come everyone's answer described multiple
argument lists and not curried functions?

Randall Schulz

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Why use currying?

the "usual way" java does it

void/def x(x:T, y:Function[String,T])
the java compiler understands that the second paramter has to be
Function if the first parameter is an integer. the
scala compiler doesn't

Am 09.10.2010 15:48, schrieb Ingo Maier:
> On 10/9/10 2:49 PM, HamsterofDeath wrote:
>> imo, it's a disadvantage that you need parameter lists for this
>
> How else would you do it?
>
> Here are a few other considerations for or against currying in Scala.
>
> 1) As Jason already mentioned, type inference is one. Another related
> thing is overloading, which is based on the first argument list only:
>
> You can do
>
> class A {
> def f(x: Int, y: Int) {}
> def f(x: Int, s: String) {}
> }
>
> but not
>
> class A {
> def f(x: Int)(y: Int) {}
> def f(x: Int)(s: String) {}
> }
>
> Well, actually, looks like I hit a bug:
>
> scala> class A {
> | def f(x: Int)(y: Int) {}
> | def f(x: Int)(s: String) {}
> | }
> defined class A
>
> scala> (new A).f(0)
> :7: error: ambiguous reference to overloaded definition,
> both method f in class A of type (x: Int)(s: String)Unit
> and method f in class A of type (x: Int)(y: Int)Unit
> match argument types (Int)
> (new A).f(0)
> ^
>
> Same for (new A).f(0)(1) and (new A).f(0)("")
>
>
> 2) Default arguments and dependent method types can only use arguments
> from previous argument lists (at least for now).
>
> You can do:
>
> def f(x: Int)(y: Int = g(x))
>
> but not
>
> def f(x: Int, y: Int = g(x))
>
> Similarily for dependent method types.
>
> 3) Convenient closure syntax (especially useful for DSLs):
>
> xs.foldLeft(x) { (a,b) => f(a,b) }
>
> instead of
>
> xs.foldLeft(x, { (a,b) => f(a,b) })
>
>
> Some of these considerations sometimes work against each other though.
> The nice dangling code block syntax can be at odds with type
> inference. For example:
>
> scala> def f[A](init: A)(iter: Int=>A) {}
> f: [A](init: A)(iter: (Int) => A)Unit
>
> scala> f(Nil) { i => List(i) }
> :7: error: type mismatch;
> found : List[Int]
> required: object Nil
> f(Nil) { i => List(i) }
> ^
>
> scala> def g[A](init: A, iter: Int=>A) {}
> g: [A](init: A,iter: (Int) => A)Unit
>
> scala> g(Nil, { i => List(i) })
>
> Ingo
>
>> Am 09.10.2010 14:38, schrieb Jason Zaugg:
>>> Arguments passed one parameter section can be used to infer the types
>>> of a formal parameter in a subsequent parameter section:
>>>
>>> http://gist.github.com/618151
>>>
>>> On Sat, Oct 9, 2010 at 9:48 AM, Outsider ..
>>> wrote:
>>>> Hi
>>>> I'm studying about currying.
>>>> But I don't know what benefit of currying.
>>>> when do I use currying?
>>
>>
>
>

imaier
Joined: 2008-07-01,
User offline. Last seen 23 weeks 2 days ago.
Re: Why use currying?

On 10/9/10 3:58 PM, Brian Maso wrote:
> Not actually a bug -- been documented on this list before. Recall that
>
> def fun(param1:T1)(param2:T2) = body
>
> Is sugar for
>
> def fun(param1:T1) = {
> (param2:T2) => { body }
> }

I refuse to recall that :)

class A {
def f(x: Int)(y: Int) {}
def f(x: Int)(s: String) {}
}

gets compiled to:

public class A extends java.lang.Object implements scala.ScalaObject{
public void f(int, int);
Code:
0: return

public void f(int, java.lang.String);
Code:
0: return

public A();
Code:
0: aload_0
1: invokespecial #21; //Method java/lang/Object."":()V
4: return

}

You might be referring to eta expansion which happens only at call site,
which you can also observe by noticing that

class B {
def f(x: Int)(y: Int) {}
val x = f(0) _
val y = f(1) _
}

generates two function classes.

As I demonstrated, you can't call any of the f's in class A above, at
least not from Scala it seems, and I am wondering why we don't give an
error at definition site similar to:

scala> class A {
| def f(x: Int) {}
| def f(x: Int) {}
| }
:7: error: method f is defined twice
def f(x: Int) {}
^

Cheers,
Ingo

>
> So if the number and type of the first param list of two functions in
> the same class are the same, you have ambiguous method overloading.
>
> Brian Maso
>
>
>>
>>
>> 2) Default arguments and dependent method types can only use arguments from previous argument lists (at least for now).
>>
>> You can do:
>>
>> def f(x: Int)(y: Int = g(x))
>>
>> but not
>>
>> def f(x: Int, y: Int = g(x))
>>
>> Similarily for dependent method types.
>>
>> 3) Convenient closure syntax (especially useful for DSLs):
>>
>> xs.foldLeft(x) { (a,b) => f(a,b) }
>>
>> instead of
>>
>> xs.foldLeft(x, { (a,b) => f(a,b) })
>>
>>
>> Some of these considerations sometimes work against each other though. The nice dangling code block syntax can be at odds with type inference. For example:
>>
>> scala> def f[A](init: A)(iter: Int=>A) {}
>> f: [A](init: A)(iter: (Int) => A)Unit
>>
>> scala> f(Nil) { i => List(i) }
>> :7: error: type mismatch;
>> found : List[Int]
>> required: object Nil
>> f(Nil) { i => List(i) }
>> ^
>>
>> scala> def g[A](init: A, iter: Int=>A) {}
>> g: [A](init: A,iter: (Int) => A)Unit
>>
>> scala> g(Nil, { i => List(i) })
>>
>> Ingo
>>
>>
>> Am 09.10.2010 14:38, schrieb Jason Zaugg:
>>
>> Arguments passed one parameter section can be used to infer the types
>> of a formal parameter in a subsequent parameter section:
>>
>> http://gist.github.com/618151
>>
>> On Sat, Oct 9, 2010 at 9:48 AM, Outsider .. wrote:
>>
>> Hi
>> I'm studying about currying.
>> But I don't know what benefit of currying.
>> when do I use currying?
>>
>>
>>
>>
>>
>>
>

imaier
Joined: 2008-07-01,
User offline. Last seen 23 weeks 2 days ago.
Re: Why use currying?

On 10/9/10 4:57 PM, Ingo Maier wrote:
> As I demonstrated, you can't call any of the f's in class A above, at
> least not from Scala it seems, and I am wondering why we don't give an
> error at definition site similar to:
>
> scala> class A {
> | def f(x: Int) {}
> | def f(x: Int) {}
> | }
> :7: error: method f is defined twice
> def f(x: Int) {}

... or

scala> class A {
| def f(x: Int, y: Int) {}
| def f(x: Int)(y: Int) {}
| }
:7: error: double definition:
method f:(x: Int)(y: Int)Unit and
method f:(x: Int,y: Int)Unit at line 6
have same type after erasure: (x: Int,y: Int)Unit
def f(x: Int)(y: Int) {}
^

but that's a different code path :)

Ingo

imaier
Joined: 2008-07-01,
User offline. Last seen 23 weeks 2 days ago.
Re: Why use currying?

On 10/9/10 4:09 PM, HamsterofDeath wrote:
> the "usual way" java does it
>
> void/def x(x:T, y:Function[String,T])
> the java compiler understands that the second paramter has to be
> Function if the first parameter is an integer. the
> scala compiler doesn't

That's not always what you want in a language with subtyping. Javac also
doesn't do what you think it does:

public class J {
T f(T t, T s) { return s; }

void g() {
Number n = f(new Integer(0), new Float(0));
}
}

Compiles for me.

Cheers,
Ingo

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Why use currying?

On Sat, Oct 09, 2010 at 04:57:41PM +0200, Ingo Maier wrote:
> As I demonstrated, you can't call any of the f's in class A above, at
> least not from Scala it seems, and I am wondering why we don't give
> an error at definition site similar to:
>
> scala> class A {
> | def f(x: Int) {}
> | def f(x: Int) {}
> | }
> :7: error: method f is defined twice
> def f(x: Int) {}
> ^

It has been opened more than once, and closed wontfix. See the comments
in this ticket:

https://lampsvn.epfl.ch/trac/scala/ticket/2628
"Ambiguous method overloading compiles, but should not"

imaier
Joined: 2008-07-01,
User offline. Last seen 23 weeks 2 days ago.
Re: Why use currying?

On 10/9/10 6:01 PM, Paul Phillips wrote:
> On Sat, Oct 09, 2010 at 04:57:41PM +0200, Ingo Maier wrote:
>> As I demonstrated, you can't call any of the f's in class A above, at
>> least not from Scala it seems, and I am wondering why we don't give
>> an error at definition site similar to:
>>
>> scala> class A {
>> | def f(x: Int) {}
>> | def f(x: Int) {}
>> | }
>> :7: error: method f is defined twice
>> def f(x: Int) {}
>> ^
>
> It has been opened more than once, and closed wontfix. See the comments
> in this ticket:
>
> https://lampsvn.epfl.ch/trac/scala/ticket/2628
> "Ambiguous method overloading compiles, but should not"
>

Thanks. I found an even older ticket in the meanwhile :)

Ingo

Brian Clapper
Joined: 2009-05-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Why use currying?

On 10/9/10 3:48 AM, Outsider .. wrote:
> Hi
>
> I'm studying about currying.
> But I don't know what benefit of currying.
>
> when do I use currying?

In addition to the answers you've already received, I documented my own
epiphany on this topic in June:

http://brizzled.clapper.org/id/102/

Raoul Duke
Joined: 2009-01-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Why use currying?

On Sat, Oct 9, 2010 at 12:48 AM, Outsider .. wrote:
> I'm studying about currying.
> But I don't know what benefit of currying.
> when do I use currying?

random by the way, seems like currying != partial application?
http://lambda-the-ultimate.org/node/2266

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland