糖衣構文

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

糖衣構文(とういこうぶん、syntactic sugar)は、プログラミング言語において、読み書きのしやすさのために導入される書き方であり、複雑でわかりにくい書き方と全く同じ意味になるものを、よりシンプルでわかりやすい書き方で書くことができるもののことである。構文上の書換えとして定義できるものであるとも言える[1]。英: syntactic sugar の直訳に近い構文糖(こうぶんとう)とも言い、糖衣構文あるいは構文糖衣とするのは少々意訳的だがよく言われている。

解説[編集]

構文糖はプログラムの意味としては同じものを、よりわかりやすい構文で書けるものである。ジャーゴンファイルのsyntactic sugarの項[2]では、アラン・パリスの「構文糖はセミコロンのガンをひきおこす」という言を引用している(ジャーゴンファイルのこの記述は、そのひとつ前の項目である「構文塩」(syntactic salt)の項[3]にある「構文塩は不健康にプログラマの血圧を上げる」という(こちらは引用ではない)記述と対応していて、colon cancer(結腸癌)とセミコロンを掛けてもいる)。

糖衣構文の例[編集]

C言語[編集]

配列へのアクセス[編集]

C言語では、配列は連続するメモリ領域に要素を並べたものとして定義され、配列の要素へのアクセスは配列の先頭要素のメモリアドレスに要素のインデックスをオフセットとして加えたアドレスの値を参照することで行われる。しかしメモリアドレスを指定するポインタを直接操作することは誤りの原因となることが多い。そこで本来ならば *(a + i) と書くところを、a[i] とも書けるようになっている。この糖衣構文はポインタ演算がより面倒になる多次元配列のアクセスを行うときに特に役に立つ。またこの糖衣構文は、括弧の手前に書かれるものが配列の先頭アドレスで括弧の中がインデックスであるというように、コードの意味をより明確で分かりやすくする。これをi[a]と記述しても構文上エラーにはならず、同じアドレスを差すため動作上も問題がない。しかし、他者(人間)がコードを読む際には誤解を招くだろう。

ポインタを介したメンバ選択演算子[編集]

C言語では、構造体へのポインタと矢印演算子によりメンバを参照できる。

p->member

ここで、p構造体へのポインタ、member は構造体の要素名である。

ポインタをデリファレンスする * 演算子と、構造体の値に対しメンバを選択する. 演算子を組み合わせて、次のように等価な式を書くことができる。

(*p).member

C++では演算子をオーバーロードできるため、これらが等価ではないケースもある。

Erlang[編集]

Erlang でのレコード型データは、実際にはタプル型データに対する糖衣構文であるが、要素を取り出したり、パターンマッチするのに糖衣構文が使われる。

%% レコードの定義(コンパイラー・マクロ)
-record(book, {title, author, lang, isbn}).

%% タプル {book, "Learn You Some Erlang for Greate Good!", "Fred Herbert", en, "978-1-59327-435-1"} になる。
B = #book{title="Learn You Some Erlang for Great Good!", author="Fred Herbert", lang=en, isbn="978-1-59327-435-1"}.

%% タプルの要素取り出し element(2, B). の糖衣構文
B#book.author.

%% タプルの要素置き換え setelement(2, B, "F. Herbert"). の糖衣構文
B#book{author="F. Herbert"}.

%% レコードのパターンマッチの部分はタプルのパターンマッチ printCover({Title, Author, _, _}) の糖衣構文
printCover(#book{title=Title, author=Author})
  -> io:format("~p by ~s~n", [Title, Author]).

Java[編集]

Javaの配列の宣言と初期化の記法

String[] strs = new String[3];
strs[0] = "a";
strs[1] = "b";
strs[2] = "c";

String[] strs = { "a", "b", "c" };

と書ける[4]String以外のオブジェクトでも可能である。 後者は「あらかじめ決まったいくつかの文字列から文字列の配列を作りたい」という記述者の思考を、より良く反映している。


ML[編集]

ここでは、ML系の言語のDerived Formsについて説明する。[5]

t_1 ; t_2 は、手続き型言語においても見受けられるように、いわゆる命令文の列であるが、型付きラムダ計算において、 (λx:Unit : t_2) t_1 と表すことができる。(ここで、Unit はユニット型 である。)

Perl[編集]

Perlの条件文の記法

if ($boolean) {
  print "Syntax sugar\n";
}

print "Syntax sugar\n" if $boolean;

と書ける。

Perlの開発者ラリー・ウォールによればこれは糖衣構文であるが、プログラマの中にはこれを読みにくいと感じる者も多い。それは、「読み書きのしやすさ」が主観に基づくためである。

注・参考文献[編集]

  1. ^ これを「マクロで定義できるもの」とするのはあまり正確ではない。C言語をはじめ、多くの言語のマクロはテキストレベルであり、構文木を自在に編集することは困難であるためである。Lispであれば「糖衣構文はマクロで定義できる」と言える。
  2. ^ http://catb.org/jargon/html/S/syntactic-sugar.html
  3. ^ http://catb.org/jargon/html/S/syntactic-salt.html
  4. ^ Java Language Specification Third Edition, 10.6
  5. ^ Types and Programming Languages ,"Pierce, Benjamin C.","ISBN : 0-262-16209-1"