オフサイドルールは、インデントによってコードブロックの境界を定義するコンピュータプログラミング言語の構文を記述します。[1] [2]
この用語はピーター・ランディンによって造られたもので、おそらくサッカーのオフサイドルールをもじったものと思われる。
オフサイドルール言語は、インデントに構文上の意味がなく、インデントが厳密にスタイルの問題である自由形式言語とは対照的です。
オフサイドルール言語は、重要なインデントを持つとも説明されます。
意味
ピーター・ランディンは、1966年の論文「次世代700プログラミング言語」で、オフサイドルールを次のように定義しました。「前の行の最初の空白以外のトークンの左側にある空白以外のトークンは、新しい宣言の開始とみなされます。」[3]
例
以下は、オフサイドルール言語としてよく使われる Pythonのインデントブロックの例です。Python では、このルールは宣言ではなく文の境界を定義するために使われます。
def is_even ( a : int ) -> bool :
% 2 == 0の 場合:
print ( 'Even!' )
Trueを返す
print ( '奇妙だ!' )
Falseを返す
関数の本体は、前の行より 1 レベル (4 スペース) 多くインデントされているため、2 行目から始まります。if句の本体は、さらに 1 レベルインデントされているため 3 行目から始まり、5 行目は 1 レベル少なくインデントされている (アウトデントされている) ため、4 行目で終わります。
制御文の行末にあるコロン ( :) は Python 構文であり、オフサイド ルールの一部ではありません。このルールは、このようなコロン構文がなくても実現できます。
実装
オフサイドルールは、 Pythonのように字句解析フェーズで実装することができ、インデントを増やすと字句解析器はトークンを出力し、インデントを減らすと字句解析器はトークンを出力します。[4]これらのトークンは、ブロックに中括弧を使用する言語の開き中括弧と閉じ中括弧に対応し、句の文法は中括弧またはインデントのどちらが使用されているかに依存しないことを意味します。これには、字句解析器が状態、つまり現在のインデントレベルを保持し、これが変化したときにインデントの変化を検出できる必要があります。そのため、字句文法は文脈自由ではなく、前のインデントレベルの文脈情報に依存します。
INDENTDEDENT{}INDENTDEDENT
代替案
インデントによるブロック区切りの主な代替手段は、C言語の幅広い使用と影響によって普及しましたが、空白文字を無視し、ブロックを中括弧(つまり、{および) またはその他の区切り文字で明示的にマークすることです。これにより、フォーマットの自由度が高まり、開発者はbreak ステートメントや continue ステートメント}などの小さなコード部分をインデントしないことを選択できますが、ずさんにインデントされたコードは、 goto failバグなど、読者を迷わせる可能性があります。
Lispやその他のS 式ベースの言語では、文と式を区別せず、括弧だけで言語内のすべての文のスコープを制御できます。中括弧言語と同様に、空白はリーダー (read 関数) によってほとんど無視されます。空白はトークンを区切るために使用されます。[5] Lisp コードの明示的な構造により、自動インデントが可能になり、人間の読者に視覚的な手がかりを提供します。
もう 1 つの方法としては、各ブロックを明示的なキーワードで開始および終了する方法があります。たとえば、ALGOL 60 とその後継言語である Pascal では、ブロックはkeywordで開始し、 begin keyword で終了しますend。一部の言語 (Pascal は除く) では、これは、改行が重要であることを意味します[要出典] (中括弧言語とは異なります) が、インデントは重要ではありません。BASICとFortranでは、ブロックはブロック名 ( など) で開始し、先頭に が付いたブロック名(例: ) で終了します。Fortran では、すべてのブロックに独自のブロック名を指定することもできます。これにより、長いコードに別のレベルの明示性が加わります。ALGOL 68とBourne シェル(sh およびbash ) は似ていますが、ブロックの終了は通常、ブロック名を逆に記述することで示されます (たとえば、 はswitch 文を開始し、対応する まで続きます。同様に、 ALGOL68 では条件文... ...[ ...[ ...]]またはforループ... ... 、 bash では... ... )。
IFENDEND IFcaseesac ifthenelifelsefi fordoodfordodone
これの興味深いバリエーションは、1 行ブロックと複数行ブロックの違いをなくした Pascal のような言語であるModula-2にあります。これにより、関数レベル ブロック以外のすべてのブロックでブロック オープナー ({または) をスキップでき、ブロック終了トークン (または) のみが必要になります。また、ぶら下がっている elseも修正されます。カスタムでは、トークンをブロックの残りの部分と同じインデント レベルに配置して、非常に読みやすいブロック構造にします。
BEGIN}ENDend
Fortranアプローチの利点の 1 つは、長いコード、ネストされたコード、またはその他の複雑なコードの可読性が向上することです。アウトデントまたは閉じ括弧のグループだけでは、どのブロックが閉じられているかに関するコンテキストの手がかりが得られないため、バックトラックが必要になり、デバッグcontinue中に綿密に調べる必要があります。さらに、END のようなキーワードに接尾辞を許可する言語では、に対してcontinue for x、インデックス変数を指定するループ終了マーカー NEXT Iに対して、に対してNEXT、一意の名前の付いたループ CYCLE X1に対して、などの手がかりがさらに向上しますCYCLE。ただし、最新のソース コード エディターでは、多くの場合、構文の強調表示などの視覚的なインジケーターや、コードの折りたたみなどの機能が提供され、これらの欠点を補っています。
生産性
Scala言語の初期のバージョンでは中括弧のみが許可されていました。Scala 3では、ブロック構造にインデントを使用するオプションが追加されました。デザイナーのMartin Odersky氏は、これがScala 3によって自身の生産性が向上した最も重要な点であり、プログラムを10%以上短くし、プログラマーを「フロー」に留めておくことができると述べ、その使用を推奨しています。[6]
注目のプログラミング言語
オフサイドルールを持つ有名なプログラミング言語:
- ABC
- アグダ
- ブー
- バディスクリプト
- コブラ
- コーヒースクリプト
- 収束する
- カレー
- エルム
- F#の初期のバージョンでは、
#lightが指定されていたが、後のバージョンでは、#light "off"が指定されていなかった[7] - GDScript (Godot エンジン)
- Haskell [8]、、、または句については
where中括弧を省略した場合letのみdocase ... of - インフォーム7
- ISWIM、ルールを導入した抽象言語
- ライブスクリプト
- ロブスター[9]
- ミランダ
- ムーンスクリプト[10] [11]
- ネメル、オプションモード
- ニム
- オッカム
- プロマル
- パイソン
- Scala、オプションモード
- Scheme、いくつかのScheme 実装要求の1 つを使用する場合、その最新のものは SRFI 119 です。
- スピン
- ウォマ
- XL
その他のファイル形式
重要なインデントを持つ、プログラミング言語以外のテキスト ファイル形式として注目すべきもの:
- GCode、RepRapFirmware 方言[12]
- ハムル
- 作成、タブインデントされた行はコマンドを表します
- Pug (旧 Jade)、Web テンプレート エンジンの比較を参照してください。
- 構造化テキスト[13]
- サス
- スタイラス
- ヤム
参照
参考文献
- ^ Hutton, G. (2012 年 12 月 6 日)。「コンビネータを使用した解析」。Davis, Kei、Hughes, John (編)。関数型プログラミング: 1989 年グラスゴー ワークショップの議事録、 1989年 8 月 21 ~ 23 日、スコットランド、フレーザーバラ。Springer Science & Business Media。pp. 362 ~ 364。ISBN 9781447131663. 2015年9月3日閲覧。
- ^ Turner, DA (2013 年 8 月 13 日)。「関数型プログラミング言語の歴史 (招待講演)」。Loidl, Hans Wolfgang、Peña, Ricardo (編)。Trends in Functional Programming: 13th International Symposium, TFP 2012、St Andrews、UK、2012 年 6 月 12 ~ 14 日、改訂版 Selected Papers。Springer。p. 8。ISBN 9783642404474. 2015年9月3日閲覧。
- ^ Landin, PJ (1966 年 3 月). 「次の 700 のプログラミング言語」(PDF) . Communications of the ACM . 9 (3): 157– 166. doi :10.1145/365230.365257. S2CID 13409665.
- ^ Python ドキュメント、2. 字句解析: 2.1.8. インデント
- ^ 「CLHS: セクション 2.1.4.7」。
- ^ Odersky, Martin (2020年6月17日). Martin Odersky: A Scala 3 Update (動画). YouTube. イベントは36:35~45:08に発生。2021年12月21日時点のオリジナルよりアーカイブ。 2021年4月25日閲覧。
- ^ Syme, Don (2009 年 5 月 20 日)。「F# 2009 年 5 月 CTP アップデートおよび Visual Studio 2010 Beta1 リリースの詳細なリリース ノート」。2019 年 1 月 21 日時点のオリジナルよりアーカイブ。
- ^ Haskell レポート – レイアウト
- ^ Lobster、ゲーム/グラフィック開発のための静的型付けとコンパイル時のメモリ管理を備えたプログラミング言語
- ^ MoonScript、Luaにコンパイルされる言語
- ^ MoonScript 0.5.0 – 言語ガイド
- ^ 「GCode メタコマンド」。
- ^ reStructuredText マークアップ仕様 – インデント
