オプションのセミコロン


10

ほとんどの場合、汎用の命令型言語では、ステートメント区切り文字としてセミコロンが必要か、完全に禁止されています(CやPythonなど)。

ただし、JavaScriptなどの一部の言語では、ステートメントをセミコロンで区切らずに、他の区切り文字(改行など)を優先できます。

この背後にある設計上の決定は何ですか?同じ行に複数のステートメントを記述する場合、セミコロンが不可欠であることを理解していますが、セミコロンを必須にする別の理由があります(以下のCを除く)?


1
ステートメントターミネータ(perl、c)、およびステートメントデリミタ(javascript、pascal)について考える必要があります。

5
Pythonでは、セミコロンを使用して、同じ行の複数のステートメントを区切ることができます。また、「空の」ステートメントを使用できるため、ほとんどのステートメントの最後にセミコロンを使用できます。
グレッグヒューギル2013年

1
I understand that semicolons are essential when writing multiple statements on the same line-言語によって異なります。私の好む方にはそのような区切り文字はまったくありません。次のステートメントは、すべての関数引数が使い果たされたときに始まります。
イズカタ2013年

1
@MichaelT:私はあなたの分類が正しいとは思わない:Perlは間違いなく両方のグループに属し、JavaScriptは実際には「ステートメントターミネーター」キャンプにあります(実装は}ファイルの前または終わりにセミコロンを推測する必要があるため)。
ruakh 2013年

はい、言語に完全に依存します。私の個人的な推測では、セミコロンは、ほとんどの言語デザイナーが従う、一種の一般に合意された規則にすぎないと思います。少なくとも、それはより自然な言語の観点からはある程度理にかなっています。ちなみに、ブロックの{および}と同じです。これらは多くの言語で使用されていますが、すべてではなく、実際にこれを行う必要はありません。これの背後に普遍的な理由はありません。
JensG 2013年

回答:


24

それらを必須にする(または完全に禁止する)と、コーナーケースの数が減り、不明瞭なバグの潜在的な原因が排除され、コンパイラー/インタープリターの設計が簡素化されます。

それらをオプションにすることを選択した言語設計者は、構文の柔軟性を高める代わりに、あいまいさを伴うことを選択しました。


7
@RobertHarvey異端者!それを行うための明白な方法は1つだけ必要です。ちなみに、perlでこれを行う方法は1つだけです。

1
ところで、一部の言語では、一般に文法にかなりの冗長性があるため、セミコロンをオプションにすることは、実際にはあいまいな場合があります。そうは言っても、セミコロンは冗長性を落とすには間違ったビットだと思います。代わりに、引数の括弧とコンマを落とすHaskellが好きです。はい、Haskellでセミコロンをドロップすることもできますが、Javascriptとは実際には同じものではありません。
Steve314 2013年

2
IIRC問題は、形式モデルに適合しないことですが、パーサージェネレーターが適切なエラーメッセージを生成しないことです。つまり、手書きのパーサーがより有用なエラーメッセージを取得できる一方で、一般的な間違いについての知識は限られています。たとえば、gccはbisonをC文法に使用するために使用されていました。同様に、問題は「エッジケース」が正式なエッジケースではなくソフトケースであることです。つまり、パーサーではASTは明確であり、人間ではASTは「明確」ですが、ASTがどのようなものであるかに同意しません。
Maciej Piechotka 2013年

2
@Maciej Piechotka-Haskellでは括弧がオプションであることを意味するつもりはありませんでした。言語設計の決定として、冗長なものを削除することについて話している。ポイントは、Haskellの関数呼び出しに括弧やコンマを使用しないことです。タプルを引数として渡すことができます、それはタプルの構文であり、引数を渡すためではありません。Haskell(およびMLなど)は、他の言語(Algol以降)にこの共通の規則があるという意味で、関数の引数の括弧とコンマを「削除」しましたが、Haskellはそれを行いません。
Steve314 2013年

1
@Maciej Piechotka-もちろん、とにかくそれが本当に普遍的な慣例になることは決してありませんでした-アルゴル語族の言語が他の言語がそれに対して自分自身を定義することを意味しないので、私の「落とされた」主張はその意味で間違っています-しかしすべてで最近のCファミリの言語は、そのような感じがします。
Steve314 2013年

15

JavaScriptは、これが非常に悪い考えであることを示しています。例えば:

return
0;

Cでは、これは値0を返します。JavaScriptではundefined、returnステートメントの後にセミコロンが挿入されるため、これが返されます。自動セミコロン挿入の詳細について知らない限り、コードが壊れている理由はすぐにはわかりません。


1
@delnan:PythonはCのように見えるように設計されていません。インデントベースであることでよく知られているため、行指向が高く、セミコロンを必要としません。JavaScriptは、技術的に行い、それらを必要とします。1つが見つからない場合は1つ挿入され、1つの構文的に有効なステートメントのように見えるものを、セマンティクスがまったく異なる2つの異なるステートメントに変換します。
メイソンウィーラー

7
これは悪い考えではありません。自動セミコロン挿入について学習する手間をかけずにJavaScriptを使用しようとする人々を混乱させるだけです。おそらく「これは非常に悪い考えです」と言う代わりに、「セミコロンをオプションにすると、外に出てすべての詳細を学ばないプログラマーに落とし穴をもたらす」とより正確に言うことができます。
TehShrike 2013年

4
@delnan:それが驚くべき理由は、JavaScriptは通常、行の最後にセミコロンを挿入しないことです。After returnは、プログラムがセミコロンなしで有効であっても、JavaScriptがセミコロンを挿入するほんの一握りのケースの1つです。(もちろん、これはメイソンウィーラーの要点を損なうものです。問題はセミコロンがオプションであることではなく、ルールが一貫していないことです。)
ruakh

6
@TehShrike:セミコロンをオプションにすることは、すべてのプログラマーに落とし穴をもたらします。なぜなら、それが意図したことを尋ねるのではなく、タイプミスを任意に解釈するからです。誰もがたまにタイプミスをします。
Jan Hudec 2013年

1
javascriptは、オプションのセミコロンの実装に欠陥があることを示しています。オプションのセミコロン自体が悪いことは示されていません。
CodesInChaos 2013年

4

セミコロンを必須にするために、文法とパーサーをいくらか単純化します。基本的に、それは字句解析プログラムが改行を含むすべての空白をダンプできるようにし、パーサーはそれについてまったく心配する必要がありません。

一方、パーサーにホワイトスペースについて伝えたいと思ったら、セミコロンをオプションにすることはそれほど難しくありません。多くの場合、whitespaceトークンと一緒にそれらをまとめることができ、パーサーはそれをうまく処理できます。

たとえば、次の一連のCステートメントにセミコロンを挿入してみてください。

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

のようにwhile(1);、実行できない奇妙なことがほとんどありますが、ほとんどの場合、最新の解析手法を使用すると、特定の区切り文字なしでステートメントの終わりを判断するのが比較的簡単です。それでも変なものを許可したい場合でも、newline_or_semicolon非ターミナルを作ることはそれほど難しくありません。


Cが元々1970年代初頭に開発されたとき、コンパイラーを簡略化するためにステートメントターミネーターが必要でした。90年代半ばまでに、Javascriptが開発されたとき、それはそれほど心配されていませんでした。
Sean McSomething 2013年

3

セミコロンは、2つの理由で文法に役立ちます。まず、長いステートメントを途方もない継続文字なしで複数行に分割できます(私はFortranとBasicについて話しています)。次に、タイプミスのために構文が本当に複雑になったときに、パーサーが構文解析を「あきらめる」方法を用意しましょう。カールビーレフェルトの例を盗んで、

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

もう1つの開いた括弧を入力したとしましょう。

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

今どこに間違いがありますか?セミコロンがある場合は、パーサーが最初のセミコロンをあきらめる方が簡単です。必要に応じて、セミコロンの後も解析を続けることができます。

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

パーサーでエラーを報告しやすくなり、エラーが発生した行/列を特定しやすくなりました。


1
FortranとBasicには、少なくとも行継続マーカーが適切に選択されています(それぞれ&および_)。。、何ものFoxProを打つラインを続行するには、あなたはセミコロンを使用し、「OMG、彼らは何を考えていた」」全くのため。
DougM

2

セミコロンは、あなたが質問で言及するように、常にオールオアナッシングとは限りません。たとえば、Luaの文法は自由形式(改行を含むすべての空白は無視できます)になるように慎重に設計されていますが、セミコロンを使用する必要もありません。たとえば、次のプログラムは同等です。

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2

0

すべての設計と構築は別として、多くのプログラマーはさまざまなバックグラウンドから来ており、セミコロンの使い方を学んだプログラマーもいなかったプログラマーもいると思います。出現しつつある新しい言語の多くは、セミコロンを必要とせず、それが存在することを許可しています。それは、より多くのプログラマーがこれらの新しい言語でコーディングする方法を学ぶための、彼らが始めたときからの習慣をあきらめる必要がない方法だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.