- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why use currying?
Sat, 2010-10-09, 08:48
Hi
I'm studying about currying.But I don't know what benefit of currying.
when do I use currying?
I'm studying about currying.But I don't know what benefit of currying.
when do I use currying?
Sat, 2010-10-09, 09:47
#2
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")
>
>
Sat, 2010-10-09, 13:47
#3
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:
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?
Sat, 2010-10-09, 13:57
#4
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?
Sat, 2010-10-09, 14:57
#5
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?
>
>
Sat, 2010-10-09, 15:07
#6
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?
>
>
>
>
>
>
Sat, 2010-10-09, 15:17
#7
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 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
Sat, 2010-10-09, 15:17
#8
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
Sat, 2010-10-09, 15:27
#9
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?
>>
>>
>
>
Sat, 2010-10-09, 16:07
#10
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?
>>
>>
>>
>>
>>
>>
>
Sat, 2010-10-09, 16:17
#11
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
Sat, 2010-10-09, 16:57
#12
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
Sat, 2010-10-09, 17:07
#13
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"
Sat, 2010-10-09, 17:17
#14
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
Sat, 2010-10-09, 20:27
#15
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:
Mon, 2010-10-11, 22:47
#16
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
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")