The Artima Developer Community
Sponsored Link

Java Community News
Function Currying in Scala

25 replies on 2 pages. Most recent reply: Mar 24, 2008 12:15 PM by James Watson

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 25 replies on 2 pages [ 1 2 | » ]
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Function Currying in Scala Posted: Mar 17, 2008 2:24 PM
Reply to this message Reply
Summary
Scala makes it straightforward for developers to specify new control structures that feel like natural parts of the language. Function currying is one technique that allows Scala to provide such natural programming constructs. Daniel Spiewak discusses function currying and its uses in a recent article.
Advertisement

One of Scala's benefits is that it allows a developer to create control structures that, while not part of the language, feel as though they were. Such control structures make programs more natural to read.

One way Scala supports such natural-looking constructs is its implementation of currying, a technique that allows the transformation of a multi-argument method into a method with a single argument. The new single-argument method returns another method, with one argument, which is the next argument in the original method's argument list.

In a recent article, Function Currying in Scala, Daniel Spiewak explains how function currying works, and illustrates its benefits:

The currying process transforms a function of two parameters into a function of one parameter which returns a function of one parameter which itself returns the result. In Scala, we can accomplish this like so:


def add(x:Int, y:Int) = x + y
 
add(1, 2)   // 3
add(7, 3)   // 10

And after currying:

def add(x:Int) = (y:Int) => x + y
 
add(1)(2)   // 3
add(7)(3)   // 10

Spiewak also shows Scala's idiomatic syntax for curried functions:

We can shorten our curried definition to something more like this:

def add(x:Int)(y:Int) = x + y
 
add(1)(2)   // 3
add(7)(3)   // 10

While at first such transformations may seem merely syntactic sugar, Spiewak points out several uses of function currying in the article

Of course, it’s not very apparent as to why this is a good idea. All we’ve really accomplished is eliminate the second parameter and move it into another function. This is a big deal in languages like Haskell which only allow a single parameter, but Scala doesn’t have this restriction...

It turns out that the best rationale for using currying has to do with general and specialized functions. It would be nice to define a function for the general case, but allow users to specialize the function and then used the specialized version on different data sets.

In the article, Spiewak illustrates the use of currying in the case of partially applied functions. What do you think of function currying in Scala?


David Linsin

Posts: 9
Nickname: dlinsin
Registered: Aug, 2007

Re: Function Currying in Scala Posted: Mar 18, 2008 12:10 AM
Reply to this message Reply
I think <a href="http://www.defmacro.org/ramblings/fp.html">this</a> article features one of the best introductions to currying.

Dave Webb

Posts: 55
Nickname: lazydaze
Registered: Feb, 2006

Re: Function Currying in Scala Posted: Mar 18, 2008 6:14 AM
Reply to this message Reply
This is cool.. you can curry Java methods using Scala:

val limitTo100 = Math.min(100.0, _:Double)
println( limitTo100(110) ) // 100.0
println( limitTo100(90) ) // 90.0

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 18, 2008 9:17 AM
Reply to this message Reply
> This is cool.. you can curry Java methods using Scala:

Indeed. Reminds me of currying Tkinter widget definitions in Python. You can specify scads of args in one fell swoop for future use.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: Function Currying in Scala Posted: Mar 18, 2008 10:03 AM
Reply to this message Reply
Geez, this is awesome! If I ever want to add 5 to two other integers, I can save typing by going

addFive(3,1)

instead of

add(5,3,1)


Oops - look like it's not only slightly confusing, it's extra typing.

Seriously, why are all the functional programming tutorials full of useless pathetic examples? I'd like to learn some FP, I can imagine it being better in multi-core worlds, but so far I'm completely unimpressed by every example / tutorial I've ever seen.

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 18, 2008 11:05 AM
Reply to this message Reply
> Seriously, why are all the functional programming
> tutorials full of useless pathetic examples?

I think it's sad in the online and print publishing worlds that it takes something like the Python Cookbook or maybe Best of Ruby Quiz to show interesting, useful examples of currying. Not that I'm an FP expert. (And I barely know Scala.) But, yeah, it's hard to mentally extrapolate from the same old addFive examples to something that makes you say, "All right. Now you're cooking."

Merriodoc Brandybuck

Posts: 225
Nickname: brandybuck
Registered: Mar, 2003

Re: Function Currying in Scala Posted: Mar 18, 2008 11:10 AM
Reply to this message Reply
Maybe Elizabeth can share her Tkinter example?

I think the easiest application of this I can visualize is the 'hole in the middle' pattern.

http://enfranchisedmind.com/blog/2007/07/10/the-hole-in-the-middle-pattern/

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 18, 2008 11:44 AM
Reply to this message Reply
Oh, dear. Now I have my homework cut out for me. I'll have to do some digging around for a Tkinter example.

In the meantime, you can poke around at Ward's Wiki, though a lot of the material is old and you won't find a coherent tutorial.

http://c2.com/cgi/fullSearch?search=CurryingSchonfinkelling
http://c2.com/cgi/wiki?CategoryFunctionalProgramming
http://c2.com/cgi/wiki?BlocksInJavaScript

The Smalltalk example about a pen at the bottom of http://c2.com/cgi/wiki?CurryingSchonfinkelling is similar to Tkinter.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: Function Currying in Scala Posted: Mar 18, 2008 12:43 PM
Reply to this message Reply
Thanks for the Hole in the Middle example - it's a good one.

I did something much like this in Java, eerily similar to his blog. There was some terrible SQL query code to return a List of objects, copied and pasted all over (with minor inconsistencies and bugs in closing the statements and connections). The only "variables" were

1) the query
2) converting a ResultSet to an Object

So, like in the Hole in the Middle article, I created an interface (ignore the extra parameter, it was needed somewhere once)


public interface IRSable<T> {

public T fromResultSet(ResultSet rs, Object extra) throws SQLException ;
}


and just passed in implementations of it, plus the query.


Personally, I didn't find the extra overhead of defining an interface and creating the classes all that burdensome. (And I could have used reflection to shortcut) But maybe if I were doing things like this a lot...

Marc Stock

Posts: 17
Nickname: salient1
Registered: Mar, 2007

Re: Function Currying in Scala Posted: Mar 19, 2008 11:16 AM
Reply to this message Reply
Dave Web's example implemented in Groovy would be:
def limiter = { x, y -> Math.min(x, y) }
def limitTo100 = limiter.curry(100)
println "limit(110): " + limitTo100(110)
println "limit(90): " + limitTo100(90)

or, short form (very bad example) would be:
def limitTo100 = { x, y -> Math.min(x, y) }.curry(100)
println "limit(110): " + limitTo100(110)
println "limit(90): " + limitTo100(90)

Joel Neely

Posts: 10
Nickname: joelneely
Registered: Mar, 2003

Re: Function Currying in Scala Posted: Mar 19, 2008 3:08 PM
Reply to this message Reply
Don't shoot the message because of the example! (or some other such mangled saying ;-)

My poster-child example for a practical use of currying is sales tax. In the state where I live, the sales tax is made up of a state portion and a local portion, along with a limit on one of them. So you could write a sales tax function with four arguments: statePct, localPct, limit, and saleAmount.

Currying allows the definition of a specialized function by fixing some, but not all, of the arguments of a more general function. So, in this case, a function for the sales tax at a specific locality is obtained by currying over the first three arguments.

It seems quite natural to say, "The sales tax function for Bigtown is the general state sales tax function with the following three values fixed:..."

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 19, 2008 8:13 PM
Reply to this message Reply
Thank you, Joel. Your Bigtown sales tax gave me an insight, FWIW:

Curry is to Function as Instantiate is to Class. Fixing some arguments while currying a function is like setting some fields while instantiating a class.

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 19, 2008 8:17 PM
Reply to this message Reply
Or perhaps: Currying is to Function as Subclassing is to Class. Fixing some arguments while currying a function is like specializing some behavior while subclassing a class.

This is all very roughly speaking, of course, and I need to ponder it some more.

Dirk Detering

Posts: 16
Nickname: det
Registered: Jul, 2005

Re: Function Currying in Scala Posted: Mar 20, 2008 3:52 AM
Reply to this message Reply
> Or perhaps: Currying is to Function as Subclassing is to
> Class. Fixing some arguments while currying a function is
> like specializing some behavior while subclassing a
> class.
>
> This is all very roughly speaking, of course, and I need
> to ponder it some more.

No, that is a good comparision. You will find currying as just happening in OO, as a special case of subclassing. So it is usable as a metapher.

Consider each function being a subclass of, say, Function implementing the static method apply.

(pseudocode)


class MyFunction extends Function {
public static SomeType apply(firstParam, secondParam) {
// some code
}
}

class MyCurriedFunction extends MyFunction {
public static SomeType apply(secondParam) {
apply( FIX_VALUE, secondParam )
}
}


result = MyCurriedFunction.apply( aValue )


Or a more rudimentary, instance based example:


class MyFunction extends Function {
protected firstParam
protected secondParam

MyFunction(first, second) {
firstParam = first
secondParam = second
}

public Object apply() {
// some code working with firstParam, secondParam
}
}

myFunc = new MyFunction( valueOne, valueTwo )
result = myFunc.apply()

class MyCurriedFunction extends MyFunction {

MyCurriedFunction(second) {
super(FIX_VALUE, second)
}

}

myFunc = new MyCurriedFunction( valueTwo )
result = myFunc.apply()

Joel Neely

Posts: 10
Nickname: joelneely
Registered: Mar, 2003

Re: Function Currying in Scala Posted: Mar 20, 2008 7:28 AM
Reply to this message Reply
I think instantiation and subclassing are reasonable analogies, at a first approximation. The core idea of specializaton/customization is one that shows up in many ways: instantiation, subclassing, currying, setting properties on a component, etc.

One interesting difference is that instantiation is an all-or-nothing affair, in that you have to supply all arguments for a valid constructor. It is certainly possible to create a subclass that fixes part, but not all, of the state/parameterization of the parent class, but I haven't seen that discussed or practiced very often. (Perhaps because of the amount of boilerplate required?)

But that sort of partial specialization seems to be a natural consequence of being able to curry a function with little "baggage".

Aside: To me, that's one of the huge benefits of studying multiple languages; learning something that's easy to express in one language may get one over the static friction of using the idea in a language which requires more baggage.

Flat View: This topic has 25 replies on 2 pages [ 1  2 | » ]
Topic: Pattern Matching with Tom Previous Topic   Next Topic Topic: Neal Gafter on Control Abstractions in the Java Closures Proposal

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use