
コンピュータサイエンスにおいて、構文糖衣とは、プログラミング言語内で、読みやすさや表現のしやすさを向上させるために設計された構文のことです。構文糖衣は、人間にとって言語をより「甘く」し、物事をより明確に、より簡潔に、あるいは好みに応じて別のスタイルで表現できるようにします。構文糖衣は通常、別の冗長な形式でも表現できる一般的な操作の省略形です。プログラマーは短い形式と長い形式のどちらを使用するかを選択できますが、通常は短い形式の方が短く、入力や読みやすいため、短い形式を使用します。
例えば、Pythonプログラミング言語では、構文 を使って指定されたインデックスにあるリスト要素を取得できますが、これは と短縮されることが多く、動作は同じであるにもかかわらず、 の方がよりシンプルで読みやすいと考えられます。同様に、は と短縮されることがよくあります。list_variable.__getitem__(index)list_variable[index]list_variable.__setitem__(index, value)list_variable[index] = value
言語におけるある構成要素が構文糖衣であるというのは、その構成要素を言語から取り除いても、その言語の機能や表現力に何ら影響がない場合を指す。
コンパイラや静的解析器などの言語プロセッサは、処理前に糖衣構文をより冗長な構文に展開することがよくあります。このプロセスは「脱糖」と呼ばれることもあります。
構文糖衣という用語は、1964 年にPeter J. Landinによって造語され、ラムダ計算の適用表現に関して意味的に定義された単純なALGOLライクなプログラミング言語の表面構文を説明するために用いられました。 [ 1 ] [ 2 ]ラムダを「where」で字句的に置き換えることを中心にしています。
後のプログラミング言語、例えばCLU、ML、Schemeなどは、この用語を拡張して、言語の中核となる基本的な構成要素によって定義できる言語内の構文を指すようになりました。便利な高レベルの機能は「脱糖」され、その部分集合に分解されることができました。[ 3 ]これは実際、プリミティブから構築していくという通常の数学的手法です。
ランディンの言語の本質的な構成要素と構文糖衣の区別に基づいて、1991年にマティアス・フェライゼンは、文献における「広く受け入れられている信念」に沿うように「表現力」の体系化を提案した。彼は「より表現力がある」とは、問題となっている言語構成要素がなければ、プログラムを完全に再編成する必要があることを意味すると定義した。[ 4 ]
MOVE A B.全くMOVE A TO B.同じ機能を果たしますが、後者の方が実行される動作がより明確になります。unless(condition){...}if(notcondition){...}statementifconditionif(condition){...}a[i]表記は の構文糖衣です*(a + i)。[ 5 ]同様に、表記は、参照解除演算子を使用してメンバーにアクセスするa->xための構文糖衣です。(*a).xusingのステートメントは、特定のオブジェクトが正しく破棄されることを保証します。コンパイラはステートメントをtry-finallyブロックに展開します。[ 6 ]auto x = exprdecltype(expr) x = exprtypeof(expr) x = expr[x*xforxinrange(10)]@staticmethod%>%パイプの前にあるデータ (または関数の出力) が、パイプの後に続く関数の最初の引数として使用されることを宣言します。[ 7 ]したがって、 はと同等です。x %>% f(y)f(x,y)JOINと同等でありINNER JOIN、後者は、結合ステートメントが外部結合操作ではなく、内部結合操作であることを明確化します。同様に、 、およびからOUTERを省略できます。LEFT OUTER JOINRIGHT OUTER JOINFULL OUTER JOINmyObject.myMethod(parameter1, parameter2, parameter3)、グローバル関数をとして呼び出すための構文糖衣です。オブジェクトへの参照は、通常メソッド内からとしてアクセスできる隠し引数として渡されます。myMethod(myObject, parameter1, parameter2, parameter3)thisusingステートメントは単一のシンボルをスコープにインポートする例であり、using namespace名前空間はその名前空間内のすべてのシンボルをスコープにインポートします。usingステートメントによって名前空間内のすべてのシンボルがスコープに追加されます。importその一例です。たとえば、を使用するとimport javax.swing.*;、プログラマーはという名前だけでSwingオブジェクトを参照できます。javax.swing.JButtonJButtonfrom importimport`文は単一のシンボルをスコープにインポートしますが、` from import *import`文はその名前空間のすべてのシンボルをスコープにインポートします。useスコープにシンボルをインポートするためにステートメントが使用されます。{name: name}は と同等です{name}。これは短縮形プロパティと呼ばれます。 (x) => x + 1(x)=>{returnx+1;}???) は と同等です。これは、まだ書かれていないコードの場所を示すのに便利です。[ 8 ]thrownewscala.NotImplementedError("an implementation is missing")プログラマーの中には、こうした構文の使いやすさに関する機能は重要でないか、あるいは全く無意味だと感じる人もいます。特に、特殊な構文形式は言語の統一性を損ない、仕様を複雑にし、プログラムが大規模かつ複雑になるにつれて問題を引き起こす可能性があります。この見解は、 Lisp のコミュニティで特に広く見られます。Lisp は非常にシンプルで規則的な構文を持ち、表面的な構文は簡単に変更できるからです。[ 9 ] 例えば、アラン・パーリスはかつて「プログラミングに関する警句」の中で、括弧で区切られた言語に言及して、「構文糖衣はセミコロンの癌を引き起こす」と皮肉を言いました。[ 10 ]
この比喩は、構文ソルトという用語を作り出すことで拡張され、これは悪いコードを書くことを難しくするように設計された機能を示しています。[ 11 ]具体的には、構文ソルトは、プログラムの動作を表現するためではなく、何が起こっているかを知っていることを証明するためだけにプログラマが乗り越えなければならないハードルです。
C#では、継承したクラス メンバーを隠蔽する場合、new隠蔽が意図的であることをキーワードで指定しない限り、コンパイラ 警告が発行されます。[ 12 ] switch 文の構文が C や C++ の構文と似ているために発生する可能性のあるバグを回避するため、C# では暗黙のフォールスルーは許可されていませんがbreak、空でないcaseラベルごとにswitch( goto、、returnまたはthrowが使用されていない限り) が必要です。 [ 13 ] (を使用してgoto後続のラベルを指定すると、C/C++ のようなフォールスルーが発生します。)
構文ソルトは、コードを読みにくくすることでその目的を損ない、結果としてコードの品質を低下させる可能性があります 。極端な場合、言語要件を満たすために導入されたオーバーヘッドよりも、コードの本質的な部分が短くなることもあります。
構文ソルトの代替手段として、コードが間違いの結果である可能性が高い場合にコンパイラ警告を生成する方法がある。これは 現代のC/C++コンパイラで一般的な手法である。
その他の拡張機能としては、構文サッカリンや構文シロップなどがあり、プログラミングを容易にしない不必要な構文を意味します。[ 14 ] [ 15 ] [ 16 ] [ 17 ]
コア構文サポートを備えたデータ型は「糖衣型」と呼ばれます。[ 18 ] [ 19 ] [ 20 ]一般的な例としては、引用符で囲まれた文字列、オブジェクト型とレコード型には中括弧、配列には角括弧などがあります。
{{cite journal}}:ジャーナルを引用するには|journal=(ヘルプ)