x < y < z
プログラミング言語で一般的に利用できないのはなぜですか?
この回答では、
- この構造は言語の文法で実装するのは簡単であり、言語ユーザーに価値をもたらしますが、
- これがほとんどの言語に存在しない主な理由は、他の機能との相対的な重要性と、いずれかの言語の統治機関の不本意によるものです。
- 潜在的に重大な変更を伴うユーザーを混乱させる
- 機能を実装するために移動します(例:怠iness)。
前書き
この質問については、Pythonistの観点から話すことができます。私はこの機能を備えた言語のユーザーであり、その言語の実装の詳細を勉強したいと思っています。さらに、CやC ++(ISO規格は委員会によって管理され、年ごとにバージョン管理されます)などの言語を変更するプロセスにある程度精通しています。
Pythonのドキュメントと実装
docs / grammarから、比較演算子を使用して任意の数の式を連鎖できることがわかります。
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
さらにドキュメントには次のように記載されています。
比較は任意に連鎖できます。たとえば、x <y <= zはx <yおよびy <= zと同等です。ただし、yは1回だけ評価されます(ただし、両方の場合、x <yが見つかったときにzはまったく評価されません)間違っている)。
論理的等価
そう
result = (x < y <= z)
論理的であると同等の評価の観点x
、y
およびz
例外を除いて、y
二回評価されます。
x_lessthan_y = (x < y)
if x_lessthan_y: # z is evaluated contingent on x < y being True
y_lessthan_z = (y <= z)
result = y_lessthan_z
else:
result = x_lessthan_y
繰り返しますが、違いはyがで1回だけ評価されること(x < y <= z)
です。
(注、括弧は完全に不要で冗長ですが、他の言語から来るもののために括弧を使用しました。上記のコードは非常に合法的なPythonです。)
解析された抽象構文ツリーの検査
Pythonが連鎖比較演算子をどのように解析するかを調べることができます。
>>> import ast
>>> node_obj = ast.parse('"foo" < "bar" <= "baz"')
>>> ast.dump(node_obj)
"Module(body=[Expr(value=Compare(left=Str(s='foo'), ops=[Lt(), LtE()],
comparators=[Str(s='bar'), Str(s='baz')]))])"
したがって、これはPythonや他の言語で解析するのは本当に難しいことではないことがわかります。
>>> ast.dump(node_obj, annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE()], [Str('bar'), Str('baz')]))])"
>>> ast.dump(ast.parse("'foo' < 'bar' <= 'baz' >= 'quux'"), annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE(), GtE()], [Str('bar'), Str('baz'), Str('quux')]))])"
そして、現在受け入れられている答えとは反対に、三項演算は一般的な比較演算であり、最初の式、特定の比較の反復可能、および必要に応じて評価する式ノードの反復可能を取ります。シンプル。
Pythonの結論
私は個人的に、範囲のセマンティクスは非常にエレガントであり、私が知っているほとんどのPython専門家は、それが損傷することを考慮するのではなく、機能の使用を奨励するでしょう-セマンティクスは評判の良いドキュメント(上記のように)で非常に明確に述べられています。
コードは、書かれているよりもはるかに多く読み取られることに注意してください。コードの読みやすさを改善する変更は、恐れ、不確実性、疑いの一般的なスペクターを上げることで割引されるのではなく、受け入れられるべきです。
では、なぜプログラミング言語でx <y <zが一般的に利用できないのですか?
私は、機能の相対的な重要性と、言語の知事によって許可された相対的な変化の勢い/慣性を中心とする理由の合流があると思います。
他のより重要な言語機能について同様の質問をすることができます
JavaまたはC#で多重継承が利用できないのはなぜですか?ここでどちらの質問にも良い答えはありません。ボブ・マーティンが主張するように、おそらく開発者は怠け者であり、与えられた理由は単に言い訳にすぎません。また、多重継承は、コンピューターサイエンスにおいて非常に大きなトピックです。確かに、演算子チェーンよりも重要です。
簡単な回避策があります
比較演算子チェーンはエレガントですが、多重継承ほど重要ではありません。JavaとC#が回避策としてインターフェイスを備えているように、すべての言語で複数の比較を行います。比較をブール値の「and」で単純に連鎖させるだけで十分に機能します。
ほとんどの言語は委員会によって管理されています
ほとんどの言語は委員会によって進化しています(Pythonのように賢明なBenevolent Dictator For Lifeを持つのではなく)。そして、私は、この問題がそれぞれの委員会から抜け出すのに十分な支援を見ていなかったと推測します。
この機能を提供しない言語は変更できますか?
x < y < z
予想される数学的セマンティクスなしで言語が許可する場合、これは重大な変更になります。そもそもそれを許可しなかった場合、追加するのはほとんど簡単です。
重大な変更
重大な変更を伴う言語について:重大な動作の変更を伴う言語を更新しますが、ユーザーはこれを好まない傾向があります。特に、機能が壊れる可能性があるユーザーはそうです。ユーザーがの以前の動作に依存している場合、x < y < z
大声で抗議する可能性があります。また、ほとんどの言語は委員会によって管理されているため、このような変更をサポートする政治的意思を得ることができないと思います。