magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

I’ve been playing around with partially applied functions in Clojure, and have hit an interesting snag when dealing with Java interop. First, lets examine what partial does in Clojure, by cribbing off an example from Stuart Halloway’s Programming Clojure:

user=> (defn add [one two] (+ one two))
#'user/add
user=> (add 1 2)
3
user=> (def increment-by-two (partial add 2))
#'user/increment-by-two
user=> (increment-by-two 5)
7

What partial is doing is partially applying the function – in our case we have applied one of the two arguments our add implementation requires, and got back another function we can call later to pass in the second argument. This example is obviously rather trivial, but partially applied functions can be very handy in a number of situations.

Anyway, this wasn’t supposed to be a discussion of partial in general, but one problem I’ve hit with it when trying to partially apply a call to a Java static method. So, let’s implement our trivial add method in plain old Java:

public class Functions {
    public static int add(int first, int second) {
        return first + second;
    }
}

Then try using partial as before:

user=> (import com.xxx.yyy.Functions)
com.xxx.yyy.Functions
user=> (Functions/add 1 2)
3
user=> (def increment-by-two (partial Functions/add 1))
java.lang.Exception: Unable to find static field: add in class com.xxx.yyy.Functions (NO_SOURCE_FILE:3)
user=> 

So it seems like the partial call can’t handle static calls in this situation. But what if I wrap the call in another function?

user=> (defn java-add [arg1 arg2] (Functions/add arg1 arg2))
#'user/java-add
user=> (def increment-by-two (partial java-add 2))
#'user/increment-by-two
user=> (increment-by-two 10)
12

Which works. There is probably a reason why, but I can’t quite work it out right now.

Advertisements

3 Responses to “Clojure, Partially Applied Functions And Java Interop”

  1. Jürgen Hötzel

    Beware that static methods are defined as MACROS by using import-static: no first class citizens.

    user> (import-static Functions add)
    #’user/add
    user> (def increment-by-two (partial add 2))
    # (def increment-by-two (partial #(add %1 %2) 2))
    #’user/increment-by-two

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS

%d bloggers like this: