web-dev-qa-db-ja.com

構文糖の厳密な定義?

言語の聖戦のように、人々は常に「単なる構文上の砂糖」であるとして特に役に立たないと思われる機能を常に否定しています。 「実際の機能」と「構文上の砂糖」の間の境界線は、これらの議論では曖昧になる傾向があります。シンタックスシュガーの合理的で明確な定義は、スピーカー/ライターが役に立たないと考える機能として定義されないようにするものだと思いますか?

9
dsimcha

これについてはどうですか:「構文糖は、意味のある抽象化レイヤーを導入しない一部の機能の便利な省略表現です。」

あなたが指摘しているように、_a->b_をとります。これは_(*a).b_と同等です。この表記は、それが有用であるか、そうでなければ隠されている方法でコードを検討することを可能にしますか?いいえ、そのため、それは構文上の砂糖です。

次に、a[i] == *(a + i)について考えます。実質的な方法で配列を使用するCプログラムについて考えてみてください。 _[]_表記なしでそれを理解しようとすることを想像できますか?多次元配列では?配列をメモリの連続したブロックの開始への参照としてではなく、全体の単位として考えることは意味があります。複雑な処理を計画している場合は、配列がCでどのように機能するかを知るのに役立ちますが、「2ビットのメモリ2 * iバイトを、 aによって参照されるメモリの場所。」配列の重要な点は、シーケンスを一貫性のある単位として格納するプロセスを抽象化する機能です。 _[]_表記は、この抽象化を容易にします。それはではない構文糖です。

これは、構文糖が常に悪いことを意味するものではありません。他の多くの異音と同様に、それは代名詞になり、「本当の特徴」に対抗しています。しかし、たとえばLISPとSchemeは、let省略形(およびその他)でないと読めません。

三項演算子_<pred> ? <cnsq> : <alt>_も別の例です。シンタックスシュガーは、プログラムを整理し、冗長なコードを削除するのに役立ちます。これにより、メンテナンスを減らすことができます。プログラミングの構文上の障壁を取り除くのに役立つ場合は、「実際の機能」を積み上げるよりも、構文上の砂糖の方が好ましい場合があります。

R ^ 5RS を引用すると、「プログラミング言語は、機能を機能の上に積み上げるのではなく、追加の機能を必要とするようにする弱点と制限を取り除くことによって設計する必要があります。」私見、構文は弱点と制限としての資格があるため、プログラマーが構文を回避できるようにすると、言語の表現力を増やすことができます。

19
Hoa Long Tam

これは、関連する概念のvery厳密な定義です:表現力
マティアス・フェライセン:

プログラミング言語の表現力について [私が見つけた唯一のフリーフォームはポストスクリプトでした。]

the Java言語とクロージャ のこのエントリも参照してください。

事実上、ローカルの変更のみを行うことで構文なしのフォームに変更できる場合、それは構文上の砂糖です。たとえば、構文形式がなければ、いくつかの異なるコードの場所を変更したり、フラグメントを他の場所に移動したりする必要がある場合、それは砂糖ではありません。

とはいえ、適切に使用すれば構文糖は問題ありません。 Schemeプログラマは、新しい無名関数を作成して適用するのではなく、let特殊形式を使用するほうがよいと思います。目的はコードをより明確にすることです。

7
Macneil

私はあなたが構文糖の定義を持つことができないと思います、フレーズはBSであり、「実際のオペレーティングシステム」で「実際のツール」を使用して「実際のプログラマ」について話す人々によって使用される可能性があるためです

「実際の機能」または「構文上の砂糖」のアイデアは 真のスコットランド人の誤謬ではない のようなものであるため、そのBSです。そのフレーズは「不当な主張を保持するための臨時の試み」です。ここでの主張は、代わりに「実際の機能」を使用できるため、ここの機能は取るに足らないものであるということです。

砂糖の使用は 回避 である必要があると主張する人がいるため、そのBSはバグを書くことができるためです それに固執する必要があります バグを書くのが難しいためです。それは素晴らしいことではありません。同じフレーズは、同じロジックを使用して、まったく反対の結論を導きます。

そのBSは、ユーザビリティの調査や欠陥数の調査を誰も引用していないため、それらの可読性や保守性、あるいは欠陥の可能性のある議論を裏付けるものです。

人々がしばしば等価であることについて間違っているか間違っているため、そのBS。たとえば この質問 は、C#文字列がchar配列の砂糖であることを表明します。 そうではありません

ただし、意味的に同等である2つのものが砂糖であると言いたい場合、それは先に進んで定義するのに役立ちます。

誰かを非難したい場合は、このフレーズを使用することもできます。

7
Conrad Frix

構文糖という用語は、同じ基礎となるセマンティクスを表現するための代替構文を示していると思います。

たとえば、任意の長さの整数のリストを追加できる演算sumを持つプログラミング言語Aを考えてみましょう。この言語では、式を書くことができます

sum []
sum [3, 4, 5, 1]
sum [2, 7]

結果はそれぞれ0、13、9です。

ここで、2つの引数でsumを使用する時間の90%を理解し、したがって、便宜上、新しい表記法を導入するとします。

2 + 7

これはsum [2, 7]syntactic sugarにすぎません。

次に、no加算演算が含まれる第2言語Bを取り上げます。 <=などの演算子を使用すると、数値を比較できますが、数値をaddする方法はありません。言語Bのリリース2では、新しいaddition操作と構文を導入しています

2 + 7

通常どおりに数字を追加します。

言語Aのコンテキストでは、+表記は構文糖sum [...]表記の代わりに使用できる代替の簡略化されたアドホック表記です) 。同様に、ホアロンタムの回答で指摘されているように、Cではp->fieldという表記は(*p).fieldの構文糖です。

言語Bのコンテキストでは、+表記は構文糖ではないです(これは、合計演算に使用される唯一の有効な構文です)。同様に、Cがポインターを介して構造体メンバーにのみアクセスでき、表記(*p).fieldがなかった場合、表記p->fieldは構文糖ではありません。

私の意見では、構文糖に関していくつかの誤解がありますが、これはプログラミング言語のセマンティクスに関する混乱にさかのぼることができます。推論は次のようになります:

  • プログラムのセマンティクスは、プログラムが計算するものです。
  • プログラミング言語の表現力は、その言語で記述できる計算によって表されます。
  • (チューリングマシンを使用して定義された)すべての計算可能な関数を記述できる2つのプログラミング言語は、同じ表現力を持っています...
  • ...したがって、構文のみが異なります。
  • 結果:チューリング完全言語の拡張は、言語の表現力を変更しないため、構文(構文糖)のみです。

上記の推論の行は、「構文糖は適切に定義できない」、「好みの問題」、または「結局のところ、すべてのプログラミング言語機能は構文糖である」などの一般的な主張につながります。

上記の議論の主な問題は、セマンティクスがプログラムによって計算できるものだけでなく、計算方法についても、つまりプリミティブ構成が何であるかだと思いますが使用され、それらがどのように組み合わされているか。

したがって、たとえばobjectsは、基礎となるビット構成とビット変換の構文糖ではなく、データと演算のモデル化と計算の記述を可能にする構成です。オブジェクト、メソッド、メソッド呼び出しを使用した計算は、バイト、プロセッサレジスタ、メモリアドレスを使用した計算とは異なります(2つの計算の結果が同じでも、2番目の計算を使用して最初の計算を実装しても)。

この説明は少し長くしましたが、他の回答で取り上げられていない重要な側面だと思います。

結論:シンタックスシュガーは、すでに言語に含まれており、明確に定義された構文とセマンティクスを備えた構成の代替(おそらくより便利な)構文です。新しい構文(構文シュガー)は既存の構文とは異なりますが、同じセマンティクスがあります。言語の新しい構成要素とその新しい構文を導入する場合、構文糖はありません。

3
Giorgio

「構文上の砂糖」は厳密に定義された用語ではありません。誰に尋ねるかに応じて、次のような定義のいずれかを取得する可能性が最も高くなります。

  1. 真のスコットランド人アプローチはありません。私が好きなのは本物のプログラミングで、私が好きでないものは構文糖です。
  2. MIPSの後のすべては構文糖であり、それらの命令のいくつかでさえおそらくおそらく必要ではありません。
  3. どこかでプログラミングを容易にするものはどれも有用であり、構文上の砂糖ではありません。ある状況で誰もその機能が役に立たなかったとしたら機能は追加されなかったので、既存の機能はすべて構文上の砂糖ではないということになります。仮説的な機能は、誰かがその機能が役立つと決定するまでは、構文上の砂糖である可能性があります。
0
Patrick87

構文シュガーは、言語表現自体を拡張しない機能であるため、冗長であり、表記法の乱用となる場合がありますが、どちらも作家の生活を簡素化し、読者に洞察を与えます。

0
Lorenzo Stella

私自身の質問に答えるために、機能は主に美学と読みやすさを向上させるために含まれている場合に限り、構文糖衣ですandは、ほぼ1対1の方法で簡単にde-に変換できます砂糖漬けバージョン。 (おおよそ1対1とは、可換演算の順序、変数名、空白などの簡単なことを意味します。)

かなりの量のプログラマの規律によってのみ砂糖を取り除くことができる機能は、構文上の砂糖ではありません。これのサブセットとして、プログラマーの規律を介してタイプセーフティを手動で強制することは非常に簡単ではないため、タイプセーフティを向上させる機能は構文糖質ではありません。たとえば、C++のオブジェクトシステムは、Cポインターキャストの多態性に加えて、単なる構文上の糖衣ではありません。

大幅なコードの複製または削除された場合の大幅な再設計のいずれかを必要とする機能は、構文上の砂糖ではありません。たとえば、テンプレートを使用せずに同等の機能を得るには、大量の複製と変更が必要になるため、テンプレートは単なる構文上の砂糖ではありません。

ある構文糖の例:

*(a + i)の代わりにa[i]

a -> bの代わりに(*a).b

イテレータ構文を手動で入力する代わりに、foreach構文。

演算子のオーバーロードはすべて純粋な構文上の砂糖です。

これは公平で合理的に明確な定義のように聞こえますか?

0
dsimcha