テーブルでのプログラミング-条件付き(だけでなく)構造を記述するための新しい概念

少し前まで、プログラミングの代替アプローチをネットワークで検索する過程で、非常に興味深いビデオに出会いました。 これは、魅力的なタイトル「No Ifs、Ands、またはButs。 条件の単純さを明らかにする" プレゼンテーションの著者であるジョナサン・エドワーズは、彼が作成したスケマティックテーブルを使用して条件構造を記述するという新しい概念について語っています。

このトピックは、プログラミングに少なくとも少し興味があるすべての人にとって興味深いものです。 40分間の余裕がない場合、または他の理由でビデオを見ることができない場合は、ジョナサンのプレゼンテーションについて簡単に語ってください。

まえがき


元のアイデアの著者は、簡単な例を使用して、回路図テーブルの主要な機能を示し、C言語(実際にはJavaですが、例では主にCサブセットを使用)の条件構造の従来の表記法と比較します。 ビデオに加えて、このトピックに関する概念もより正式な言語で説明されている記事があります。 このリテールは、プレゼンテーションの最も興味深い瞬間を簡単に伝えることを目的としているため、著者が操作する数学的詳細の一部を省略し、例と比較に焦点を当てています。

回路図表


まず、関数fib例として使用して、スケマティックテーブルの構造を検討します。 入力として1つのパラメーターnを取り、フィボナッチ数列から数を返します。その数はnの値に等しくなります。 関数のソースコード:
int fib( int n) {
assert(n >= 0);
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n - 1)
+ fib(n - 2)
}


* This source code was highlighted with Source Code Highlighter
.
この関数のスケマティックテーブルの形式は次のとおりです。

図  1. fib関数の概略表

最初の列は変数を記録します。 この例では、入力パラメーターinと戻り値out 2つしかありません。 2列目にはアサーションが含まれます。 ここでは、入力パラメータの非負性を確認するために使用されます。 後続のすべての列は条件を記録します。 Assert後の最初の列は、 in == 0場合in == 0 true、 n == 1場合は2番目、 n >= 2場合は3番目と見なされます。

したがって、列は条件を担当します。 次に、テーブルの行がアクションを担当します。 それらには、上から順に下に向かって順番に実行される機能が含まれています。 fib関数のスケマティックテーブルで定義された一連のアクションを書き留めましょう。
  1. in < 0場合、エラー( Assert列の条件が満たされない場合の標準的な動作)を報告し、実行を完了します。
  2. in == 0場合in == 0を返します。
  3. in == 1場合in == 1を返します。
  4. in >= 2場合、次の手順に進みます。
  5. in - 1の結果を入力パラメーターとしてfib再帰呼び出しにfibます。
  6. in - 2の式の結果を2番目の再帰関数呼び出しに渡します。
  7. 両方の再帰呼び出しから取得した値を加算した結果を返します。
次に、関数の正確性をチェックする単体テストを作成しましょう。 これを行うのは非常に簡単です-新しい空の関数を作成し、 Assert列で実行する必要があるステートメントを記述し、 Assertの横の次の列で、テストする関数の無条件呼び出しを記録し、目的の値を渡します。 関数の結果は、「=」列に表示されます。 この場合、テストはfib testと呼ばれfib test

図  2.進行中のfib関数

図からわかるように、関数の入力パラメーターとして3が渡され、2が返されましたAssert列のエントリは、関数の結果がエラーにならないことを意味します。 右側のテーブルは、関数fibに対して作成したものと同じスケマティックテーブルであることに注意してください。ここでは、「=」という名前の別の列を追加しました。 さらに、条件が満たされていない列は灰色で塗りつぶされます。 この場合、最後の列の条件( 3 >= 2 )が満たされ、2つの再帰呼び出しから取得した値を関数fibに追加した結果が得られます。

すべての中間値を表示する機能は、回路図テーブルの優れた機能の1つです。 ジョナサンはスプレッドシートからこのアイデアを借りたと主張しています。 スプレッドシートでは、すべての値がその場で計算されます。 上の図でカーソルがある青い矢印をクリックすると、 fib関数の再帰呼び出しに対応する別のテーブルが表示されます。 このプロセスはさらに続行できます。 次の各テーブルでは、現在の呼び出しでどの列が真であるか、およびテーブルの各行で実行された操作の値を確認します。

図  3.再帰的な関数呼び出しの開示

この機能により、デバッグプロセスが快適なものになる可能性があります。

そのため、簡単な例で、スケマティックテーブルの主な機能を調べました。 次に、より複雑な例を見てみましょう。これは、回路図テーブルの疑いのない利点の1つを示しています。

スイッチ(switch-statements)


スケマティックテーブルを使用して切り替え条件を想像してみましょう。 行ったダメージを計算する方法があるゲームを書いているとします。 それをdamageと呼びましょう。 攻撃の種類、その驚き、および攻撃者の防御レベルに基づいて、このメソッドは特定のダメージ値を返します。

メソッドのソースコード:
enum Attack {Magic, Melee};

int damage(Attack attack, bool surprise, int defense) {
int power;

switch (attack) {
case Magic:
power = 5;
break ;

case Melee:
power = 4;
break ;
}

int effectiveness = power * (surprise ? 3 : 2);

switch (attack) {
case Magic:
if (effectiveness >= defense)
return effectiveness - defense;
return 0;

case Melee:
return (effectiveness / defense) * 2;
}
}

* This source code was highlighted with Source Code Highlighter
.
対応するスケマティックテーブル:

図  4.損傷方法の概略表

まだ出会っていないテーブルの要素を考えてみましょう。 まず、いくつかの入力パラメーターがあり、それぞれが特定のタイプに属します。 次に、 Assert列の後に、新しいTrue列が表示されます。 常に実行される無条件のアクションが含まれています。 第三に、最初の列では、入力パラメーターと戻り値に加えて、別のタイプの変数-ローカル変数が登場しました。 厳密に言えば、名前のない各行は匿名のローカル変数です(これは、前に説明した単体テストの表で明確に示されています)。 ただし、場合によっては、文字列に名前を付けて、その後の操作や関数でその値を使用できるようにすると便利です。

したがって、上から下に移動し、左から右に考えると、次の一連のアクションになります。
  1. 攻撃の種類に基づいて、ローカル変数のpowerを5または4に設​​定します。
  2. 予期しない攻撃の兆候に基づいて、匿名ローカル変数を3または2に設定します。
  3. ローカル変数のeffectiveness 2つの変数の積の結果を割り当てます。その値は、パラグラフ1および2で決定されました。
  4. attack == Magic場合、 defense変数の値をeffectivenessから引きます。
  5. attack == Magic & defense <= 0場合、値0を返します。
  6. attack == Magic & defense >= 1場合、減算のeffectiveness - defense結果を返します。
  7. attack == Melee場合、式のeffectiveness / defense * 2結果を返しますeffectiveness / defense * 2
例からわかるように、 True列(項目3)の操作は、キューに到達すると常に実行されます。特定の条件の充足に依存しません。 他のすべての操作は、現在の入力パラメーターのセットに対して条件が真である列から選択されます。

水平線は、表で定義された条件間のデータフローを示しています。 したがって、水平線の存在は、常に、ある条件で(または無条件に)計算されたデータが別の条件で計算されることを示します。

damage方法のソースコードと、同じフォントサイズの対応するスケマティックテーブルの視覚的な比較:
図  5.損傷方法のソースコードとその回路図表の比較

左側では、画面上の構造のサイズが2つの異なる記録方法と比較され、右側では、方法のロジックのインターレースが明確に示されています。 プログラムロジックのテキストエントリにはディメンションが1つしかないため、この例では「交通渋滞」が発生します。中央の緑色のセクションは2つの条件ブロックの間に配置されます。 これにより、たとえば、 attack == Magic条件が満たされた場合の実行結果を知りたい場合、コードが少し難しくなります。 スケマティックテーブルの場合、 ロジックアクションは互いに直交する2つの異なる軸に配置されます。 そして、ここで回路図テーブルの概念の基本原則に到達します-コードを1次元ではなく2次元で表現します。

図  6.スケマティックテーブルの概念の基本原理

テーブルの水平軸では、 決定が行われます。 条件を記述するために、ブール代数のセマンティクスが使用されます。
縦軸は、入力パラメーターと戻り値によって相互接続された関数のグラフの形式で記述されたアクションが実行されます。

それでも回路図テーブルの概念に懐疑的であれば、次の図をご覧になることをお勧めします。

図  7.スケマティックテーブルのシンプルさと汎用性

ネストされたif-then-else条件、スイッチ式、さらにはポリモーフィズム(ここでは説明しません)などのタイプの条件構造は、スケマティックテーブルを使用するときにすべて単一の形式になります。 私の意見では、これは良い兆候です。 ここでは、Albert Einsteinを引用するのが適切です。
すべてをできるだけシンプルにする必要がありますが、シンプルではありません。

この記事では、テーブルの構造に大きな変更を加えないため、ポリモーフィズムを考慮しませんでした。 Javaメソッドのオーバーライドをスケマティックテーブル形式のレコードで置き換える方法の例は、29分からのプレゼンテーションビデオで始まります。

おわりに


説明した概念は、Jonathanが開発したプログラミング言語Coherenceの基礎となるいくつかの興味深い機能の1つです。 記事のスクリーンショットは、ビデオプレゼンテーションで作成されました。 著者は、回路図テーブルでのインタラクティブな作業、その編集と実行、および単体テストの作成のためのツールを提供するシェルを開発しました。 このすべての動作をビデオで見ることができます。 また、作成者は、Windows用の実行可能ファイルと共にシェルソースコード(C#で記述)をアップロードしました。 [ ダウンロード ]

回路図表の概念の正式な説明を含む記事を含む、トピックに関する追加資料は、 www.subtextual.orgにあります。 著者にはブログもあります。 めったに更新されませんが、他の興味深いアイデア、たとえば共同アクションなどの説明を見つけることができます。

ジョナサンのイデオロギーをよりよく理解するために、彼がやや急進的なマニフェストに慣れることができます。彼は、現在受け入れられているソースコードの形でのプログラムロジックの記録に反対し、プログラミングを開発する新しい方法を提供します。

ご清聴ありがとうございました。

UPD:
コメントでは、人々は実際に回路図表を適用することの妥当性について疑問を呈しています。 状況を少し明確にしようと思います。

プログラムロジックを記録するこの方法は、完全な開発として位置づけられるものではありません。IDEをコンパイラで記述し、それを大衆に投入するだけです。 これは現時点での概念です。 私の意見では、それはプログラミングの分野における現在の状況についてのいくつかの考えにつながります。 私はhabrasocietyがそれについて学ぶのは面白いだろうと決めました。なぜなら、最近の分野の新しい傾向から、既存のプログラミングパラダイムに基づいた新しい言語の出現しか見ることができないからです。並列コンピューティングの組織。

UPD2:
誤報をおaびします。 C#で記述されたシェルソースコードとWindows用の実行可能ファイルは、プロジェクトサイトからダウンロードできます。FAQセクションの最初の質問を参照してください 。 サブテキストは以前の名前でしたが、プロジェクトの名前はCoherenceになりました


PS記事の執筆スタイルやデザインについてコメントがある場合は、コメントに記入するか、私に個人的に連絡してください。 どんな批判も喜んでいます。

Source: https://habr.com/ru/post/J80893/


All Articles