7

I have a Java class that has access to a transaction context that I'd like to use from Scala. So I thought that I'd write a Java method that takes a Scala function and calls it inside the transaction -

class Context {
    @Transactional public void runInTx(Function0<scala.Unit> f) {
        f.apply();
    }

So far so good. I'd like to be able to pass a Scala closure to it

def deleteItems(ids: Set[Long]) = {
  context.runInTx { ids foreach { dao.delete(_) } }
}

but can't because runInTx isn't actually call by name, and ids foreach { dao.delete(_) } isn't actually a Function0.

Now I can solve this problem with a small thunk

def deleteItems(ids: Set[Long]) = {
  def localApply(f: => Unit) = context.applyInTx(f _)
  localApply { ids foreach { dao.delete(_) } }
}

but it seems to me that I need a lambda function to produce an unnamed Function0 out of a code block.

Does such a thing exist in the API, or how would I go about writing it?

1 Answer 1

11

You can tell the compiler to interpret the block as a function rather than a statement to be called immediately by adding the (in this case lack of) parameters.

So in this case:

def deleteItems(ids: Set[Long]) = {
  context.runInTx {() => ids foreach { dao.delete(_) } }
}

() => ids foreach { dao.delete(_) } is the full form of the function literal. The compiler allows the parameter list to be omitted in places where it can infer that a function is required - this is true for call by name, but doesn't seem to be true when passing to a method taking a Function

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

Comments

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.