2

私は Ceylon を初めて使用し、JavaScript エンジンと JVM の両方で実行できるように、TypeScript (本質的には JavaScript) で記述された既存のソフトウェアを Ceylon に移植する方法を現在模索しています。

セイロンでこのJavaのものと同等のものをコーディングする方法を知っている人はいますか?

public class Engine { ... } // Some given class definition

public interface Cont extends Callable1<Cont,Engine> {}

ここCallable1<Y,X>で、 は Ceylon の に相当する Java ですCallable<Y,[X]>

アイデアはCont、たとえば名前付きのインスタンスは、c別の を返す関数Cont、またはnull.

Java では、これを使用するコードは次のようになります。

// Somewhere
public static void exec(Cont c, Engine e) {
  while (c != null) c = c.call(e);
}

(これは本質的にトランポリンであり、呼び出された各関数が継続を返すかnull、計算が完了したときに行われます。)

また、Ceylon では、関数を Cont のインスタンスとして渡したいと考えています。


返信を読んだ後、適切な結果の入力 (Cont?の代わりにAnything) とnull-testing (パフォーマンスのため) の両方を使用する次のソリューションにたどり着きました。

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);
    }
}

これは、毎回追加の小さなオブジェクトを作成し、関数を渡すという犠牲を払って、私には合っていますwrap

4

2 に答える 2

3

のカスタム実装については議論Callableされていますが、まだ可能ではありません。ただし、それは必要ありません。

shared class Engine() {
    // ...
}

shared interface Continuation {
    shared formal Continuation? call(Engine engine);
}

shared void execute(variable Continuation? continuation, Engine engine) {
    while ((continuation = continuation?.call(engine)) exists) {}
}

object continuation satisfies Continuation {
    call(Engine engine) => null;
}

// usage
execute(continuation, Engine());

// usage in 1.2 with inline object expression
execute(object satisfies Continuation { call(Engine engine) => null; }, Engine());

Continuationを満たさない (できない) ので、Callable関数を渡すだけではいけません。しかし、次のリリース (1.2、現在 GitHub から入手可能) では、少なくともインライン オブジェクト式を使用できるようになります。

これは慣用的な Ceylon ではなく、Java からのかなり直接的な翻訳であることに注意してください。

于 2015-02-18T21:10:04.273 に答える
1

これはコンパイルされているように見えますが、かなりひどいものに見えます:

class Engine() {}

Anything(Engine) foo(Engine e) {
    return foo;
}

// Somewhere
variable Anything(Engine)? f = foo;
while (is Anything(Engine)(Engine) f2=f) {
    f = f2(e);
}
于 2015-02-18T21:07:19.753 に答える