「イディオム」は、特定の言語では整数インクリメントなどのコア言語構文によって単純化されない一般的な操作またはパターンであると理解しています。
i = i + 1;
C ++では、このイディオムは演算子によって簡素化されます。
++i;
しかし、誰かが「イディオマティック」という用語を使用するとき、どのようにそれを理解するかわかりません。コードの一部を「イディオマティック」にするものは何ですか?
「イディオム」は、特定の言語では整数インクリメントなどのコア言語構文によって単純化されない一般的な操作またはパターンであると理解しています。
i = i + 1;
C ++では、このイディオムは演算子によって簡素化されます。
++i;
しかし、誰かが「イディオマティック」という用語を使用するとき、どのようにそれを理解するかわかりません。コードの一部を「イディオマティック」にするものは何ですか?
回答:
あるコードを書く慣用的な方法は、他の言語にはない言語固有のイディオムのために、非常に特定の方法でそれを書くときです。
たとえば、C ++では、RAIIイディオムを活用することで、慣用的なリソースを管理するC ++コードを作成する方法につながります。
もう1つの例は、Pythonでリスト内包表記を使用してリストを生成することです。慣用的なPythonでリストの内包表記を使用していましたが、他の言語やPythonでもジェネレーター関数を使用して同じことを行うことができたため、これは慣用的です。
多くの場合、この言語固有のイディオムを使用せずに新しい言語を試す人は、慣用的なコードを作成しません。
TryAdd()
Generic Dictionary
クラスで呼び出される拡張メソッドを作成して最初にチェック!Contains()
してから呼び出すとAdd()
、これは慣用的でしょうか?C#に固有の機能-拡張メソッドを使用しています。
通常の定義
ネイティブスピーカーにとって自然な表現の使用、包含、または表示
プログラミング定義
[Insert Language]プログラマーにとって自然な表現の使用、包含、または表示
プログラミングの文脈での慣用的な表現は、通常、「言語で何かを表現する最も自然な方法」と定義できます。
Rubyでは、イディオマティックという言葉が特に多く登場します。Rubyには、大規模なメタプログラミング機能があり、慣用的なRubyコードを作成するには、通常これらを使用する必要があります。
コードがイディオムであるという理由だけで、それがクリーンまたは簡潔であることを意味しないことに注意してください。多くの場合、妥協する必要があります。
したがって、基本的に、慣用句は最も一般的には、言語で何かを書く最も一般的な方法を指し、しばしば「スラング」(イディオム)を含みます。コードの一部が慣用的でない場合、完全に読みやすく、簡潔で、きれいで、正しいかもしれませんが、使用されている言語では気まずく感じます。このようなコードを慣用的に書き換えることは実際には良いことであり、ケースバイケースで判断する必要があるかどうかは好みの好みです
たとえば、慣用的な英語は地域によって異なります。単語の使用bum
はおそらく慣用的な英国英語にbutt
は必要ですが、米国英語にはより適切です。(悲しいことに英国の英語はあまり知りません:/)
頭の中で、イディオムな何かのために考案できる最良の例は、Rubyから来ています。
豊富な言語で、次のように反復できます。
for( start; end; increment){
code;
}
または非常によく似たもの。多くの言語にもforeach(x in SetOfXes)
構造があります。しかし、Rubyのイディオムである反復には、次のようなものが含まれます。
collection.each do |current|
current.do_stuff
end
そしてさらに
10.times do |x|
puts x
end
これらは、あまり一般的ではない何かを行う方法を表し、その領域の哲学の中核にある何かを表すので、これらを慣用的と見なします。Rubyには、オブジェクトとの相互作用に関する哲学がありますが、それは一意ではありませんが、遍在的ではありません。
セマンティックノートでは、イディオマティックという言葉を聞くたびに、私の脳は自動的に「...へのイディオマティック」という考えを完成させます。
collection.each do |current|
違いforeach(current in collection)
ますか?どちらものcurrent
各要素に設定されるループ構造ですcollection
。
通常、イディオムは、一般的な比較的複雑な状況を言語で表現するための最良の方法です。インクリメントは、イディオムでもありません。接尾辞の代わりに接頭辞インクリメントを使用すると、C ++のイディオムであると主張できます。
熟語は、専門家のユーザーによって決定された言語を使用する最良の方法です。実際のC ++イディオムは関数オブジェクトです。別のイディオムはRAIIです。言語には、デストラクタのリソースを解放する必要があることを伝えるものは何もありません。しかし、そうすることは慣用的です。別の例としてはテンプレートがあります。テンプレートを使用するのは慣習的ですが、可能な限りすべてのものを使用しますが、継承の過剰使用を妨げるものは何もありません。
あなたの定義は正しいとは思いません。イディオムは、他の言語では可能であるかもしれないし、そうでないかもしれない何かを書く方法ですが、それはこの言語では一般的です。通常、代替よりも短いですが、それは実際には要件ではありません。
非イディオマティックなものについて話すことで、それを説明する方が簡単かもしれません。C ++では、次のように書くのがかなり慣用的です。
Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p)
{
// whatever
}
書くことはさらに慣用的です:
Foo* p;
if(p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
{
// whatever
}
このコードはまったく同じことを行います。C++を初めて使用する一部の人は、pが関数が返す値と等しいかどうかをテストするためにそれを読むかもしれませんが、それはそうではありません。
別の言語から来た誰かが非常に非定型的に書くかもしれないものと比較してください:
Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p !=NULL)
{
// whatever
}
また、このようなものが非イディオマティックとしてノックされていることがわかります。
if (x>0)
return true;
else
return false;
慣用的なアプローチは
return (x>0);
非イディオマティックな方法は間違っていませんが、イディオムを知っている人にとっては、タイプするのに時間がかかり、読むのに常に時間がかかります。私があなたを「オオカミを泣かせた少年」と呼んで、あなたが物語を知っているなら、それは私が誤った警報が人々にあなたを無視させる原因を説明するよりも速いです。もちろん、問題は、あなたが物語を知らず、オオカミが私たちが話していることとどう関係しているのか分からない場合です。同様に、これまでに見たことがなくreturn x<y;
、実際にそれが何をするのか分からない場合、問題になる可能性があります。
if(Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y))