2017-12-24 17 views
1

がここに私のコードです原因:俳優でclassキーワードを置き換えると、エラー

class Eapproximator 
    var step : F64 
    new create(step' :F64) => 
    step = step' 

    fun evaluate() :F64 => 
    var total = F64(0) 
    var value = F64(1) 
    while total < 1 do 
     total = total + step 
     value = value + (value * step) 
    end 
    value 

actor Main 
    new create(env: Env) => 
    var e_approx = Eapproximator(0.00001) 
    var e_val = e_approx.evaluate() 
    env.out.print(e_val.string()) 

それがうまく機能して印刷2.7183(予想通り)。私はEapproximator定義でactorclassを交換した場合しかし、私はエラーの束を得る:

Error: 
/src/main/main.pony:18:34: receiver type is not a subtype of target type 
    var e_val = e_approx.evaluate() 
           ^
    Info: 
    /src/main/main.pony:18:17: receiver type: Eapproximator tag 
     var e_val = e_approx.evaluate() 
        ^

    /src/main/main.pony:6:3: target type: Eapproximator box 
     fun evaluate() :F64 => 
    ^
    /src/main/main.pony:3:3: Eapproximator tag is not a subtype of Eapproxim 
ator box: tag is not a subcap of box 
     new create(step' :F64) => 
    ^
Error: 
/src/main/main.pony:19:19: cannot infer type of e_val 

    env.out.print(e_val.string()) 

が、私はこれを修正するために何ができますか?

答えて

2

アクターは、ポニーの並行処理の単位です。これは、あなたのMainEapproximatorのアクターを含め、同じプログラム内の多くの異なるアクターが同時に実行できることを意味します。アクターのフィールドが複数のアクターによって同時に変更された場合、どうなりますか?並列プログラムが現代のハードウェア上で動作する方法のため、最終的にごみの価値を得る可能性が最も高いでしょう。これはデータ競争と呼ばれ、同時プログラミングの多くの多くのバグの原因です。 Ponyの目標の1つは、コンパイル時にデータ競合を検出することです。このエラーメッセージは、実行しようとしていることが潜在的に安全でないことを示すコンパイラです。

このエラーメッセージを確認してみましょう。

レシーバタイプは、受信機タイプと呼ばれるオブジェクト、ここでe_approxの一種であるターゲット・タイプのサブタイプ

ありません。ターゲットタイプは、メソッド内にタイプthis、ここではEapproximator.evaluateです。サブタイプ化とは、サブタイプのオブジェクトがスーパータイプのオブジェクトであるかのように使用できることを意味します。その部分はタイプの不一致のためe_approxevaluateが呼び出せないことを伝えています。

受信機タイプ:Eapproximatorタグ

e_approxEapproximator tagあります。 tagオブジェクトは読み取ることも書き込むこともできません。私はなぜe_approxtagであるかを詳細に説明します。

ターゲット・タイプ:evaluateの内部Eapproximatorボックス

this

Eapproximator boxあります。 boxオブジェクトを読み取ることはできますが、書き込むことはできません。 thisevaluateが暗黙のうちに意味fun evaluate、として宣言されているためfun box evaluate(デフォルトでは、メソッドが自分の受信機を変更することができないことを意味します。)boxある

EapproximatorタグがEapproxim インフレータボックスのサブタイプではありません:タグではありませんボックス

のsubcapこのエラーメッセージによると、tagオブジェクトは、それがboxたかのようにtagが使用できないことを意味boxオブジェクトのサブタイプではありません。 tagboxが許すのは、論理的です。 boxtagよりも多くのことを許します:tagは読むことができません。スーパータイプよりも少ない(または多くの)ものを許可する場合、そのタイプは他のタイプのサブタイプにしかなりません。

なぜclassactorに置き換えると、オブジェクトはtagになりますか?これは私が以前に話したデータ競争の問題と関係があります。俳優は自らの分野を自由に統治する。それは彼らから読んでそれらに書き込むことができます。アクターは同時に実行することができるので、フィールドの所有者とのデータ競合を避けるためには、それぞれのフィールドへのアクセスを拒否する必要があります。型システムには、正確には何かがあります:tag。俳優はtagと他の俳優だけを見ることができます。なぜなら、俳優との読み書きは安全ではないからです。これらの参照でできることは、非同期メッセージ(beメソッド、またはビヘイビアを呼び出して)を送信することです。これは、読み取りも書き込みもないためです。

もちろん、Eapproximatorの突然変異を行っていないので、あなたの特定のケースは安全です。しかし、安全でないプログラムを禁止するのは、それに加えてすべての安全なプログラムを許可するよりもはるかに簡単です。

Eapproximatorをクラスとして維持する以外は、プログラムの修正は実際にはありません。ポニープログラムの俳優になる必要はありません。アクターは並行性の単位ですが、それは連続性の単位でもあることを意味します。シーケンシャルとシンクロナイズが必要な計算は、単一のアクタ内に存在しなければなりません。次に、これらの計算をさまざまなクラスに分類して、優れたコードの衛生状態を整えることができます。