How can I call a callback function in xtend?
I am looking for something similar to the one in C.
Example:
struct callbacks
{
char name[10];
boolean (*pfState)();
};
static const struct callbacks call[] = {
{"YOURS", &isOwner},
{"OURS", &our_owner}
};
So, I will just call it like this: call[0].pfState().
I have created a similar ArrayList in xtend.
val you = new youModule()
val our = new ourModule()
val callbacks = newArrayList('YOURS' -> you.isOwner, 'OURS' -> our.isOwnder);
Am I doing this correctly? How can I execute the function call in the pair?
Currently you create a list of Pairs which map strings to the result of the method invocation, e.g. assuming #isOwner returns a boolean, your list callbacks is currently a List<Pair<String, Boolean>>.
Instead, you have to wrap the invocation of #isOwner in a lambda expression:
val callbacks = newArrayList(
'YOURS' -> [| you.isOwner ],
'OURS' -> [| our.isOwnder ]
);
Now, callbacks has the type List<Pair<String, ()=>boolean>>, or in other words: List<Pair<String, Functions.Function0<Boolean>>>.
If you have a "callback" stored in a variable, you need to invoke the function by calling apply on it.
Here is a simple example showing a hash map that contains two callbacks stored under 'YOURS' and 'OURS' key. When called, each callback function prints a different message and returns a boolean value.
val callbacks = newHashMap(
'YOURS' -> [| println("calling the first callback"); true ],
'OURS' -> [| println("calling the second callback"); false ]
)
val result = callbacks.get("YOURS").apply
// result is: true
// console output is: calling the first callback
Related
def fun(f: Int => Unit) {
f(10)
f(20)
}
println("method 1 call:")
fun(i => {println("hi"); println(i)})
println("method 2 call:")
fun{println("hi"); println(_)}
The output is:
E:\test\scala>scala i.scala
method 1 call:
hi
10
hi
20
method 2 call:
hi
10
20
I think i => {println("hi"); println(i)} and println("hi"); println(_) are the same. Because we have one parameter and the parameter is used just once, we can use _ to simplify the code.
Then, why does method 2 just print "hi" once?
(Does it mean: if I want to use _ to simple the calling, the contents on the right of => just can have one expression, if have more than one, e.g. println("hi"); println(i); Then, we can not use _ to replace?
println(_) expands to x => println(x), so {println("hi"); println(_)} expands to {println("hi"); x => println(x)}. So when fun{println("hi"); println(_)} executes, the following steps take place:
The expression {{println("hi"); println(_)}} is evaluated. Which means:
println("hi") is evaluated and then
x => println(x) is evaluated, creating a function object that will print its argument.
The thus-created function object is the result of the expression.
The method func is called with the created function object as its argument. func will call the function with 10 and 20, causing it to print those numbers.
First, you have to know that in scala { block; of; code } is an expression that evaluates to whatever the last expression inside it evaluates to.
When you say:
fun(i => { println("hi"); println(i) })
you create an anonymous function, which body contains 2 expressions, both returning () and both are evaluated when function is called, everything as expected.
But when you say
fun({println("hi"); println(_)})
You pass in a block, not an anonymous function. As sepp2k explained this expands to
{ println("hi"); x => println(x) }
So, you pass a block to fun, this block is being evaluated before it is passed. So first println("hi") happens, it is printed just once as block is evaluated once, and then this x => println(x) is evaluated, which is a function Int => Unit, that prints its argument. This, and only this (as a last expression is passed to the fun. This is why each time you call fun it just prints the argument twice.
To see further on how block could work you can look at this example that does more in the block
fun {
println("building the function")
val uuidOfThisFunction = UUID.randomUUID
x => println(s"$uuidOfThisFunction, $x")
}
So this block prepares a function giving it some extra context through the closure. This uuid will stay the same for both calls that happen if fun.
building the function
86e74b5e-83b5-41f3-a71c-eeafcd1db2a0, 10
86e74b5e-83b5-41f3-a71c-eeafcd1db2a0, 20
The example that would look more like what you did with first call would be
fun(
x => {
println("calling the function")
val uuidOfThisCall = UUID.randomUUID
println(s"$uuidOfThisCall, $x")
}
)
The block evaluates every time f is called.
calling the function
d3c9ff0a-84b4-47a3-8153-c002fa16d6c2, 10
calling the function
a0b1aa5b-c0ea-4047-858b-9db3d43d4983, 20
I have defined method double.
def double(i: Int): Int = i * 2
val p = double {
print("Hello!");
5
}
print(p)
As you can see we can pass not just integer argument, but we also can invoke some logic (print). Why can I do that? And how Scala do resolve it? What does really mean {} in Scala?
Your code is equivalent to:
val p = double({ //`{}` still means a block of code
print("Hello!")
5
})
or even:
def block = { //might be `def block() { ... }`
print("Hello!")
5
}
val p = double(block) //calling the block here, it's equivalent to double(block())
So it's just syntactic sugar to help developers to build some handy DSLs, which are looking like native language parts.
In this case {} means anonymous block of code. The result of invocation of code block equals to the last block's expression result.
Your code equivalent to this one
val p = double( {
print("Hello!");
5
})
Code block evaluation result is a parameter for double.
This works because block evaluation result is 5 and have Int type.
Function params evaluation doing before body of function will invoke.
First expression of code block is print and therefor print("Hello!"); will be called first. The last expression is 5 and take as function parameter.
val p = double(5)
And then print result of double is 10.
Total result of this code is printing to console
Hello!10
As aforementioned, the last expression of an anonymous block is returned; (obviously) nested anonymous blocks works as well,
val p = double {
val a = 2
val b = { println("Hello!"); 3 }
a+b
}
Hello!
p: Int = 10
Note p type conveys the return type declared for double.
Likewise,
val p = double { 2 + { println("Hello!"); 3 } }
Hello!
p: Int = 10
def myfunc():Int = 10
class FuncUser( val func:()=>Int )
val i = new FuncUser( myfunc )
This fails because myfunc is immediately evaluated -- its type is Int, not ()=>Int
How can directly pass myfunc to the FuncUser constructor?
Also, this works:
val y4:()=>Int = myfunc
val j = new FuncUser( y4 )
but I'm confused about why the first line succeeds? Why isn't myfunc also immediately evaluated in this second example?
You use partial application to "lift" the method (it's not a true function) myfunc to a Function0:
val i = new FuncUser(myfunc _)
I have not understood the following code snippet why afterDelay(0) {...}, a locally defined function can be stored into agenda? Can someone help me understand the afterDelay(0) {...} in the run function?
abstract class Simulation {
type Action = () => Unit
case class WorkItem(time: Int, action: Action)
private var curtime = 0
def currentTime: Int = curtime
private var agenda: List[WorkItem] = List()
private def insert(ag: List[WorkItem], item: WorkItem): List[WorkItem] = {
if (ag.isEmpty || item.time < ag.head.time) item :: ag
else ag.head :: insert(ag.tail, item)
}
def afterDelay(delay: Int)(block: => Unit) {
val item = WorkItem(currentTime + delay, () => block)
agenda = insert(agenda, item)
}
private def next() {
(agenda: #unchecked) match {
case item :: rest =>
agenda = rest
curtime = item.time
item.action()
}
}
def run() {
afterDelay(0) {
println("*** simulation started, time = "+
currentTime +" ***")
}
while (!agenda.isEmpty) next()
}
}
afterDelay(0) {
println(...)
}
Is equivalent to the following:
afterDelay(0)({
println(...)
})
The function afterDelay is invoked a new WorkItem (item) is added to the list, not the function itself. The parameter block: => Unit is a "By-Name Parameter" (see the Scala Language Specification section 4.6.1): the expression used as the argument is implicitly converted into a "parameterless method" (without being evaluated first) that will be invoked whenever the variable inside the method is accessed (no () required).
In this case that is when the function resulting from () => block is invoked: it is invoked at item.action() which occurs at some point after the new WorkItem is added to the list (and afterDelay returns).
If it was written as (taking in a function paramater, not a by-name/thunk):
def afterDelay(delay: Int)(block: () => Unit) { // take a function
// new function will invoke function named by "block" when invoked ...
val item = WorkItem(..., () => block())
// or skip wrapping the function in a function ...
// val item = WorkItem(..., block)
...
}
Then it would need to be invoked passing in a function:
afterDelay(0)(() => { // need a function
println(...)
})
Or, alternative syntax, still a function of () => Unit, but the outside parenthesis can be avoided:
afterDelay(0) { () => // need a function
println(...)
}
Extract from the SLS, 4.6.1 By-Name Parameters:
The type of a value parameter may be prefixed by =>, e.g. x: => T. The type of such a parameter is then the parameterless method type => T. This indicates that the corresponding argument is not evaluated at the point of function application, but instead is evaluated at each use within the function. That is, the argument is evaluated using call-by-name.
You defined afterDelay as a curried function. This means it has two parameter lists. In scala you can replace the brackets surounding the parameterlist (...) with {...}. In the second parameterlist you are using a "call-by-name" parameter. Those parameters are evaluated everytime again you use them in your function. A good Example is here.
"Call-by-name" parameters are often used to define your own controlling structure.
def do(until: Int)(body: => Unit) {
body
if (until > 1) do(until - 1)(body)
}
do(0)(println("test"))
do(5)(println("test2"))
This is an example for a do until. It will print once test and five times test2.
Given this code:
def getFunc(funcName:String, param:Int) = match funcName {
case "FooFunc" => FooFunc(param)
[...]
}
def FooFunc(param:Int) = param + SomeObject.SomeVariable
How could I return FooFunc with param applied, without evaluating it? The reason I'd want to do this is because FooFunc, as you can see, relies on an external variable so I'd like to be able to call it with param already applied. What would the return type of getFunc need to be?
Easy:
def getFunc(funcName: String, param: Int) = funcName match {
case "FooFunc" => () => FooFunc(param)
[...]
}
Your method has a good name: getFunc is supposed to return a function, so it will.
The lazyness must be defined at the call site, in Scala. You can do:
lazy val x = getFunc(...) // getFunc only gets evaluated when needed
Or you can change the signature:
def FooFunc(param:Int) = () => param + SomeObject.SomeVariable
...
val x = getFunc(...) // x contains a function from Unit into something
x() // Use x here, causing the evaluation
You could add another void parameter, so the function is only evaluated when it is applied to this parameter.
Though I'd rather use a proper object instead of a function in this case.
I'm sure there's many options, but you can use:
return { Unit => FooFun(param) }