0

Is it possible, in Scala, to define a function that would receive any other function as a parameter?

It should be something like the following:

object Module extends SecureModule{ val bc = new MyBC() def method(parameter: Type) = { exec(bc.method(parameter)) } def method2(parameter1: Type1, parameter2: Type2) = { exec(bc.method2(parameter1,parameter2)) } } trait SecureModule { def exec(f: ANY_PARAMETER => ANY_RESULT) = { //some extra processing f } } 

is it possible? If so, how could I achieve this?

Thank you in advance.

1
  • The text ANY_PARAMETER => ANY_RESULT is slightly, but importantly, misleading in that it implies that there is always one parameter, whereas you apparently want this to work with a function of any arity. Similarly, the invocation f (which should presumably be f()) implies that there are no arguments. Arity is the real problem here; for a given arity, abstracting over the types is simple. Commented Jul 24, 2015 at 6:37

3 Answers 3

2

The nice thing about scala is that you can create what seems to be your own syntax.

If what you want to do is wrap an operation so that you can do pre and post processing, as well as control the execution context, then you do this by using call-by-name parameters. For example, if we just wanted to time how long a block of code takes, then we could do something like this:

def timer[T](block: => T): (T,Long) = { val startDate = new Date() val result = block val endDate = new Date() (result, endDate.getTime()-startDate.getTime()) } 

We can use it like this:

val (result,duration) = timer { 1+3 } 

Or like this

val (result,duration) = timer { "hello" + " world!" } 

And the result will have the correct type from the block that you pass in while also giving you the duration that you expect.

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

1 Comment

As soon as it got closer to the approach I was looking for, I will accept this as the answer. Thank you!
1

I am under the impression that your description is somewhat misleading. The way I understand it, what you (might) want to do is delaying the execution of the bc.method calls until some other code has been performed. If so, try this:

object Module extends SecureModule{ val bc = new MyBC() def method(parameter: Type) = { exec(() => bc.method(parameter)) } def method2(parameter1: Type1, parameter2: Type2) = { exec(() => bc.method2(parameter1,parameter2)) } } trait SecureModule { def exec[Result](f: () => Result): Result = { //some extra processing f() } } 

Comments

0

You can't take any function as a parameter. What would you even do it?

At best, you can take any function that has a specific number of parameters.

For example, here, f takes one argument and returns a value.

def exec[A,B](f: A => B) 

And here, f takes two arguments:

def exec[A,B,C](f: (A, B) => C) 

If you don't care about the return type of the function, you could always use Any instead of a type parameter, since functions are covariant in their return type:

def exec[A](f: A => Any) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.