6

Here at work most people use Java, while I am working with Scala. We have decided to gather some common classes in an library which will be written in Java. Now I want to add some pseudo-functional programming to the library, take a look at the following:

java:

public interface Func<A, R> {
    public R f(a A);
}

public AClass {
    public <R> ArrayList<R> myMethod(
                             Func<String, R> func
    ) {
        // ...
    }
}

usage in java:

AClass ac = new AClass();
ArrayList<String> al = ac.myMethod(
                            new Func<String, String> (
                                public String f(String s) {
                                    return s + "!";
                                }
                            })

The above is not exactly exiting (more like daunting actually, from a scala perspective). Is there any way to summon some scala magic to be able to do something like the following in scala:

var ac = new ACLass
var al = ac.myMethod(str => str + "!")             // alternative 1
al = ac.myMethod { case: str:String => str + "!" } // alternative 2

I messed around with implicits for a while but couldn't get things sorted out =P.

2
  • Have you tried creating an adapter in Scala that takes in a lambda and mutates it into an anonymous inner class for the library to consume? I'm not sure if you'll get this to work with compile-time generics though... Commented Sep 20, 2011 at 7:05
  • I did, but I didn't get it to work =) Commented Sep 20, 2011 at 7:18

3 Answers 3

13

With implicit conversions:

object FuncConversions {
  implicit def func2function[A,R]( fn: (A) => R ) =
    new Func[A,R] {
      def f(a: A) = fn(a)
    }
}

Don't forget to import the conversion in your scope:

import FuncConversions._

You can also implement the opposite conversion.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh crap, now I get it. I was trying that very same code but with def f = fn _ instead, which gave: <console>:8: error: _ must follow method; cannot follow func.type. Thanks!
6

To expand on paradigmatic answer. Here is how you go about figuring out the implicit. Implicit conversions come into play when the types don't check. When that happens, the compiler will search for an implicit conversion to use so that types match.

After cleaning up your example a bit, in the REPL, the compiler would show:

scala> ac.myMethod((s:String) => s + "!")
<console>:9: error: type mismatch;
 found   : String => java.lang.String
 required: Func[java.lang.String,?]
              ac.myMethod((s:String) => s + "!")

So the compiler tells you it found a (String) => (String) but needs a Func[String, ?]. Therefore you want to provide an implicit conversion between the found type and the required type. So the signature should be something like:

implicit def fun2Func(fun: (String) => String): Func[String,String]

Then, the next step is to realize that the implicit conversion can be generalized with types A and R.

On a sidenote, I wonder if you'd be better of by re-using something of the shelf like http://code.google.com/p/guava-libraries/.

2 Comments

+1 for using guava instead of home grown Func. Someday they will become part of JDK :)
Valid advise based on me leaving out my attempted implementation. guava is definitely a good option! I'll look into it when I have more time to spend on the library.
3

I don't know exactly but maybe functional Java http://functionaljava.org/ could help you and your collegues. What functions exactly you try to gather in your 'pseudo-fp' lib?

1 Comment

Our library is not focused on functional programming, I merely needed to pass functions as arguments while doing some database interaction stuff, to be able to clean up the resources before returning. With java being what it is, I think the functional programming will be at a minimum in the library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.