I am new to Ceylon, and am currently exploring how to port some existing software written in TypeScript (essentially JavaScript) to Ceylon, so that it can run both on JavaScript engines and JVM.
Does anybody know how to code an equivalent of this Java stuff in Ceylon:
public class Engine { ... } // Some given class definition
public interface Cont extends Callable1<Cont,Engine> {}
where Callable1<Y,X>
is a Java equivalent of Ceylon's Callable<Y,[X]>
.
The idea is that an instance of Cont
, say named c
, would be a function either returning another Cont
, or a null
.
In Java, the code using this would look like:
// Somewhere
public static void exec(Cont c, Engine e) {
while (c != null) c = c.call(e);
}
(This is essentially a trampoline, where each called function returns the continuation, or null
when the computation is done.)
Also, in Ceylon I would like to pass functions as instances of Cont.
After reading the replies, I've come up to the following solution which uses both the proper result typing (Cont?
instead of Anything
), and null
-testing (for performance):
shared interface Cont { shared formal Cont? call(Engine e); }
// A wrapper class for an actual continuation function
class ContWrap(Cont?(Engine) fun) satisfies Cont {
shared actual Cont? call(Engine e) => fun(e);
}
shared Cont wrap(Cont?(Engine) fun) {
return ContWrap(fun);
}
// Somewhere
shared void exec(variable Cont? cont) {
while (exists cc = cont) {
cont = cc.call(this);
}
}
This suits me, at the cost of creating an additional small object every time, and passing functions through wrap
.