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 ]
Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: Function Currying in Scala Posted: Mar 20, 2008 8:44 AM
Reply to this message Reply
Advertisement
> Maybe Elizabeth can share her Tkinter example?

Here are some situations in which currying does the trick:
* You want to define a function which takes several arguments, but your programming language allows only one arg per function.
* You have a function which takes several arguments, but you need to supply a function which takes fewer args.
* You want to supply default values for some of a function's args.
* You have a function whose default argument values don't suit you.

A Python Tkinter GUI callback can be "any Python function that takes no arguments" (http://docs.python.org/lib/node698.html). The question becomes what to do if you want to use an argument-taking function for your callback. You need to somehow feed the args to the function now without actually calling the function now, then pass the function itself with its fixed args to the Tkinter widget so that it can be called by the GUI later. Currying to the rescue.

Let's ignore Tkinter for a moment and just illustrate currying itself. First, we'll define a utility function to do the currying:

def curried(fun, *first_args, **some_kwargs):
def _fun(*later_args, **more_kwargs):
all_args = first_args + later_args
many_kwargs = some_kwargs.copy()
many_kwargs.update(more_kwargs)
if verbose: print repr(all_args), repr(many_kwargs)
fun(*all_args, **many_kwargs)
return _fun

Then we'll define an interesting function:

def box(color='gray', x=0, y=0, dx=0, dy=0):
print '%s box from (%d,%d) to (%d,%d)' % (color, x, y, x+dx, y+dy)

The box function can be called without arguments, but we don't like its defaults. So let's curry it a few ways and call it a few ways:

small_box = curried(box, dx=10, dy=10)
small_red_box = curried(small_box, color='red')
small_red_centered_box = curried(small_red_box, x=(1024-10)//2, y=(768-10)//2)

verbose = True
small_box()
small_box('orange')
small_box(x=200, y=100)
small_red_centered_box(x=(1680-10)//2, y=(1050-10)//2)
curried(box, 'green', (1024-500)//2, (768-500)//2, 500, 500)()

The above code produces the following output:

() {'dx': 10, 'dy': 10}
gray box from (0,0) to (10,10)
('orange',) {'dx': 10, 'dy': 10}
orange box from (0,0) to (10,10)
() {'y': 100, 'x': 200, 'dx': 10, 'dy': 10}
gray box from (200,100) to (210,110)
() {'y': 520, 'x': 835}
() {'color': 'red', 'y': 520, 'x': 835}
() {'color': 'red', 'y': 520, 'x': 835, 'dx': 10, 'dy': 10}
red box from (835,520) to (845,530)
('green', 262, 134, 500, 500) {}
green box from (262,134) to (762,634)

The Tkinter function for creating a button can be called as follows:
Button(master, text='foo', command=callback)
. We would like a button callback to simulate the drawing of a large, green, centered box using our box function:
Button(frame, text='Draw Box', command=curried(box, 'green', (1024-500)//2, (768-500)//2, 500, 500))


All right. Now you're cooking--with Curry.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: Function Currying in Scala Posted: Mar 20, 2008 5:22 PM
Reply to this message Reply
Thanks for the more realistic examples. They give me a feel for "Currying" and I can imagine cases where it's useful. I'm still not sure it's all that big a deal, in Java there are usually multiple constuctors or call signatures filling in default values, and nobody blogs on how that's all powerful, but whatever. :-)

Ramzi Ben Yahia

Posts: 23
Nickname: miccheck
Registered: Jul, 2002

Re: Function Currying in Scala Posted: Mar 21, 2008 3:21 AM
Reply to this message Reply
Currying is not for filling default values.

// takes a size and an int
// and pads the int with left 0's to fill the size
// returns the string
def pad(size: Int)(i: Int) : String = ...
// obvious
def pair[A](x: A) = (x,x)
// hours list (as options for <select />)
def hours = (0 to 23) map (pad(2)_ andThen pair)

If I hadn't currying for the pad function I should have written

.. map ({ x: Int => pad(2,x)} andThen pair)
// or something that will traverse the list 2 times
map (pad(2,_)) map (pair)


I wish that the '_' will disappear somehow in scala, making methods all curried by default .
So currying is useful when used with higher order functions, composition (or other combinators).

Joel Neely

Posts: 10
Nickname: joelneely
Registered: Mar, 2003

Re: Function Currying in Scala Posted: Mar 22, 2008 3:12 PM
Reply to this message Reply
Ramzi, you can avoid the _ if you use functions instead of methods. I've posted a more complete discussion of the sales tax example, complete with code that sidesteps the _ issue, at http://joelneely.wordpress.com/2008/03/22/currying-without-lab-rats/ .

Ramzi Ben Yahia

Posts: 23
Nickname: miccheck
Registered: Jul, 2002

Re: Function Currying in Scala Posted: Mar 22, 2008 3:36 PM
Reply to this message Reply
> Ramzi, you can avoid the _ if you use functions instead of
> methods. I've posted a more complete discussion of the
> sales tax example, complete with code that sidesteps the _
> issue, at
> http://joelneely.wordpress.com/2008/03/22/currying-without-
> lab-rats/ .

Right, but what I expect today from a language like Scala is to sweep out these subtleties (the least surprise rule). It's tiresome to have things that work in some contexts and not in others. I'm not a language designer, but why there's a difference between functions and methods? Especially when we're allowed to assign methods to functions.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Function Currying in Scala Posted: Mar 22, 2008 5:49 PM
Reply to this message Reply
> This is a big deal in languages like Haskell which only allow a single parameter, but Scala doesn’t have this restriction...

You make it sound like Haskell is deficient in that respect.

The fact is, Haskell and OCaml are extremely powerful precisely because their functions accept single parameters and integrate currying at an extremely basic level.

In Scala, currying seems like an afterthought. I'm not saying that's bad, but it make its use less natural.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Function Currying in Scala Posted: Mar 22, 2008 5:52 PM
Reply to this message Reply
> Thanks for the more realistic examples. They give me a
> feel for "Currying" and I can imagine cases where it's
> useful. I'm still not sure it's all that big a deal, in
> Java there are usually multiple constuctors or call
> signatures filling in default values, and nobody blogs on
> how that's all powerful, but whatever. :-)

Currying can be very powerful. If you get a chance, take a look at a Haskell or OCaml tutorial. Currying can make it easy to compose functions in ways that tend to force the use of quite a few classes when you don't have it as a feature.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Function Currying in Scala Posted: Mar 23, 2008 6:39 PM
Reply to this message Reply
> Thanks for the more realistic examples. They give me a
> feel for "Currying" and I can imagine cases where it's
> useful. I'm still not sure it's all that big a deal, in
> Java there are usually multiple constuctors or call
> signatures filling in default values, and nobody blogs on
> how that's all powerful, but whatever. :-)

I'm not functional expert but I think to truly understand the value of function currying you have to have a little experience in functional programming.

I think a better OO analog to this over 'class is to subclass' is an immutable Object implementing an interface which is constructed with any number of parameters and then passed to a method for it's methods to be called.

The best example of this I can think of off the top of my head is the way DataSources are used. A class that works with numerous database connections will take a DataSource instance as a parameter. Basically this interface provides one important method: getConnection(). But in order to fulfill this contract, the DataSource instance may need a number of parameters of its own and may even need to call on other Objects. The ability to construct this instance with an arbitrary number of dependencies without affecting the way that client code interacts with the DataSource solves basically the same kind of problem. Currying makes functions a little more like objects, IMO.

A big difference is that function currying tends to be a lot less verbose to what you need to do to produce the same kind of behavior in something like Java. That is, it tends to be used more because it is more convenient to do so. I say this is a good thing because this type of approach tends to produce more reusable code than procedural approaches.

Ramzi Ben Yahia

Posts: 23
Nickname: miccheck
Registered: Jul, 2002

Re: Function Currying in Scala Posted: Mar 24, 2008 5:17 AM
Reply to this message Reply
> > Thanks for the more realistic examples. They give me a
> > feel for "Currying" and I can imagine cases where it's
> > useful. I'm still not sure it's all that big a deal,
> in
> > Java there are usually multiple constuctors or call
> > signatures filling in default values, and nobody blogs
> on
> > how that's all powerful, but whatever. :-)
>
> I'm not functional expert but I think to truly understand
> the value of function currying you have to have a little
> experience in functional programming.
>
> I think a better OO analog to this over 'class is to
> subclass' is an immutable Object implementing an interface
> which is constructed with any number of parameters and
> then passed to a method for it's methods to be called.
>
> The best example of this I can think of off the top of my
> head is the way DataSources are used. A class that works
> with numerous database connections will take a DataSource
> instance as a parameter. Basically this interface
> provides one important method: getConnection(). But in
> order to fulfill this contract, the DataSource instance
> may need a number of parameters of its own and may even
> need to call on other Objects. The ability to construct
> this instance with an arbitrary number of dependencies
> without affecting the way that client code interacts with
> the DataSource solves basically the same kind of problem.
> Currying makes functions a little more like objects,
> , IMO.
>
> A big difference is that function currying tends to be a
> lot less verbose to what you need to do to produce the
> same kind of behavior in something like Java. That is, it
> tends to be used more because it is more convenient to do
> so. I say this is a good thing because this type of
> approach tends to produce more reusable code than
> procedural approaches.
I don't see subclassing as an analogy for currying
it's more about morphing an object into another by fixing some of it's state. In the case of functions (which are objects in scala) "fixing some of the state" is applying the function to a number of expected parameters, and functions morph into other functions of lesser order.
The power comes from the fact that from the same code you create different interfaces
in the following example I create from the simple code a < b 3 kind of predicates
Granted this code is really ugly, but that's what we can achieve by writing the 4 lines of scala code

// scala
def lessThan = (a:Int) => (b:Int) => a < b
def flip[a,b,c](f :a => b => c) : b => a => c = (y) =>(x) =>f(x)(y)
println(List(4,0,3) filter (lessThan(2)))
println(List(4,0,3) filter (flip(lessThan)(2)))


import java.util.*;
public class Predicates{
  public static interface Pred0{
    boolean eval();
  }
  public static abstract class Pred1<T>{
    public abstract boolean eval(T t); 
    public Pred0 toPred0(final T t){ 
      return new Pred0(){
        public boolean eval(){ return Pred1.this.eval(t);}
      };  
    }   
  }
  public static abstract class Pred2<T,U>{
    public abstract boolean eval(T t,U u); 
    public Pred1<U> toPred1_1(final T t){ 
      return new Pred1<U>(){
        public boolean eval(U u){ 
          return Pred2.this.eval(t,u);
        }   
      };  
    }   
    public Pred1<T> toPred1_2(final U u){ 
      return new Pred1<T>(){
        public boolean eval(T t){ 
          return Pred2.this.eval(t,u);
        }   
      };  
    }   
  }   
  public static <T> Collection<T> filter(Collection<T> col,Pred1<T> pred){
    LinkedList<T> list = new LinkedList<T>();
    for(T item : col ){
      if(pred.eval(item)) list.add(item);
    }   
    return list;
  }
  public static void main(String[]args){
    Pred2<Integer,Integer> lessThan = new Pred2<Integer,Integer>(){
      public boolean eval(Integer a, Integer b){ return a < b ; } 
    };  
    Collection<Integer> col = new LinkedList<Integer>(){{ add(4); add(0); add(3); }}; 
    System.out.println(filter(col,lessThan.toPred1_1(2)));
    System.out.println(filter(col,lessThan.toPred1_2(2)));
  }
  if(lessThan.toPred1_1(3).toPred0(4).eval()){
      System.out.println("yes 3 is less than 4");
    }
 
}

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: Function Currying in Scala Posted: Mar 24, 2008 11:21 AM
Reply to this message Reply
I realize it's a bit of apples to oranges, but I like James' DataSource example. Here's one from me - does it makes sense? Let's say you are trying to figure out something about the Milky Way. If a function you were passing in as part of this was messy and something that somebody else would want to change for their calculation, say, an estimate of the total mass of the universe, you should curry this out.

Slightly off-topic, but this is a bit of an area where my brain apparently works differently than many. I prefer an API with fewer, more generic methods, but (to counter balance) will accept more parameters to each method. Where others prefer APIs with many, more specific methods, each with fewer parameters. As a Java example, if my class has a java.util.Properties with 3 "well known" keys, "foo", "bar", and "goo", I may define three static Strings to represent them, but the actual API would almost always be

String get(String key);


Many others will "curry" this and write specific getters

String getFoo();
String getBar();
String getGoo();


I guess my taste doesn't run to curry. Though I love a good Indian cup of Chai. :-)

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Function Currying in Scala Posted: Mar 24, 2008 12:15 PM
Reply to this message Reply
> Many others will "curry" this and write specific getters
>
> String getFoo();
> String getBar();
> String getGoo();

I would say calling this 'currying' is a huge stretch. It achieves the opposite effect of currying. Currying makes it easier to reuse existing code through making it possible for a caller providing n parameters to call one defined with n + m parameters.

The above is as about as far away from that as possible.

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