言語に論理演算子としての含意が含まれないのはなぜですか?


60

奇妙な質問かもしれませんが、なぜ多くの言語(Java、C、C ++、Python Haskell-最後のユーザー定義演算子はそれを追加するのは簡単ですが)で論理演算子としての意味がないのですか?論理的含意を書くと(特にアサートまたはアサートのような式で)否定するか、またはORを使用して否定する方がはるかに明確です。

encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}

28
それはCに入れられなかったからです。それが置かれていれば、C ++、Java、C#がそれを持っているでしょう。
m3th0dman

4
しかし、Cはアセンブリ言語の一般的な部分ではないため、Cにはありません。私が知っているすべての命令セットが含まれているかどうかにかかわらず、暗示を含むものはありません。まもなく誰かが私に教えてくれるあいまいな命令セットを教えてくれます...
ジャック・エイドリー

4
(1)「^」、「v」、「〜」よりも原始的ではないため、(2)「A => B」は「〜A v B」と同等であるため、入力をほとんど節約しないため、冗長と見なされた可能性があります。
ジョルジオ

4
論理構造を扱う言語はそれを持っている可能性が高いです。これらの主なものはプロローグです

9
assert#1が#2よりも明確だと思うのには驚いています。私はしばらくの間#1を見つめていましたが、それがどのように直観的であると考えられるかはまだわかりません。(特に余分な!=ロジックの反転)
クリスバートブラウン

回答:


61

たまに持っておくと便利です。このような演算子に反対するいくつかの点があります。

  • 文字->は、単独でも組み合わせても価値があります。多くの言語はすでに他のことを意味するためにそれらを使用しています。(そして、多くの人は構文にユニコード文字セットを使用できません。)
  • 含意は、プログラマーのような論理志向の人にさえ、非常に直感に反します。4つの真理値表のエントリのうち3つがtrue多くの人を驚かせるという事実。
  • 他のすべての論理演算子は対称的であり->、直交性の例外となります。
  • 同時に、簡単な回避策があります:演算子!とを使用し||ます。
  • 含意は、論理的and/ よりもはるかに頻繁に使用されorます。

これがおそらく今日のオペレーターが珍しい理由です。確かに、新しい動的言語がすべてにユニコードを使用し、オペレーターのオーバーロードが再び流行になるにつれて、より一般的になる可能性があります。


22
最初のポイントは、演算子のシンボルとして「->」を使用することのみに反対し、実際に演算子を持つことには反対しません。その他は良い点です。
AShelly

14
「同時に、簡単な回避策があります:use!および&&。」:実際、「->」(または数学ではより一般的である「=>」)をシミュレートする最も簡単な方法は、!and ||、not !および&&A -> Bは、!A || Bwhichと同等!(A && !B)です。
ジョルジオ

22
「4つの真理値表エントリのうち3つが真の驚きであるという事実は、多くの人々を驚かせます。」ワット。私はかなり頻繁に使用される同じ機能を持つ別の演算子を知っています
...-l0b0

9
@ l0b0、私はCSを勉強したプログラマーですが、それはずっと前のことです。「暗黙」は、真理値を返す2つのオペランドを持つ正式な操作であることを忘れていたため、最初はこの質問の性質に戸惑っていました。日常のスピーチでは、第1オペランドが真であることがすでにわかっている場合にのみ「暗黙」を使用します(「Xは真なので、Yは真でなければなりません」)。しばらくして、私は形式的な「暗黙」がどのように機能するかを思い出しましたが、事実は残っています-かつて正式な論理を勉強した人でさえ、その意図は私には明らかではありませんでした。そして、もし私がそれを一度も研究していなかったら、それは最終的には意味がなかったでしょう。
ベン・リー

5
(a)Cでは->が演算子として使用されます。それについて文句を言う人はいません。とにかく=>を使用します。(b)誰に直観に反する?含意の定義はまさにそれ、定義です。(c)減算は可換ではありません。それについて文句を言う人はいません。(d)私はあなたが意味すると思う!および||。多くの場合、優先順位(および)も必要です。&&または||;に対して同じ引数を使用できます。好きなものを選んでください。(e)おそらく、ほとんどの言語ではないためです。||の多くの用途 簡潔かつ(少なくとも私にとって)直感的に含意に置き換えることができます。
セオドアノーベル

54

答えは数学の基礎にあると思います。含意は通常、ブール代数の基本的な操作ではなく、派生した操作として考えられ、定義されます。プログラミング言語はこの規則に従います。

これは、ジョージブールの「思考の法則の調査(1854)」の第2章の命題Iです。

推論の手段としての言語のすべての操作は、次の要素で構成される記号のシステムによって実行される場合があります。

1日 概念の主題として物事を表すx、y、&cなどのリテラルシンボル。

2番目。同じ要素を含む新しい概念を形成するために物事の概念が結合または解決される心の操作を表す、+、-、×などの操作の兆候。

3番目。アイデンティティのサイン、=。

そして、これらの論理記号は、代​​数科学の対応する記号の法則に部分的に同意し、部分的に異なる明確な法則に従って使用されています。

Booleの符号+は、ブール「or」と集合の両方として今日認識されているのと同じ「心の働き」を表します。同様に、記号-および×は、ブール否定、セットの補数、ブール「アンド」およびセットの交差に対応します。


+1-確かな答え。ブール代数とそれが可能にするロジックの簡素化は、多くのプログラミング方法論を推進します。「暗黙...」を使用すると、「気にしない」状態を妨げる可能性があります。

3
1.それは定義に依存します。または定義することができますa || b = !(!a && !b)(私は会ったまたは論理の派生演算子として)。2.それが行われる理由は、通常、帰納法を単純化するためです(派生演算子は単なるショートカットであるため、個別のケースを用意する必要はありません)。@ GlenH7:どのような「気にしない」条件ですか?a --> bはと同じ!a || bです。
マチェイピエチョトカ

3
また、 -私たちは(XORのような他の派生演算子を持っている!=()NXOR ==)...
マチェイPiechotka

5
実際、NAND !(a && b)またはNOR からすべてを引き出すことができます!(a || b)。たとえば、NOT a == a NAND aa AND b == NOT(a NAND b)a OR b == (NOT a) NAND (NOT b)。ただし、NAND演算子のみを提供すると、難解な言語の領域に移動します(回答者のユーザー名を考えると、これは驚くほどうまく適合します;-))。
ステファンMajewsky

1
@Stefan:IMPLからすべてを引き出すこともできます。
メイソンウィーラー

37

更新:この質問は2015年11月の私のブログの主題でした。興味深い質問をありがとう!


Visual Basic 6(およびVBScript)にはImpand Eqv演算子がありました。誰も使用していません。どちらもVB.NETで削除されました。私の知る限り、誰も文句を言いませんでした。

私は1年間Visual Basicコンパイラチームで(インターンとして)働いていましたが、VBがこれらの演算子を持っていることさえ一度も気づきませんでした。私がVBScriptコンパイラを書いている人ではなかったので、実装をテストしなければならなかったなら、おそらく気付かなかっただろう。上の男ならば、コンパイラチームが機能について知らないし、それを使用していない、それはあなたの機能の人気と有用性についての何かを伝えます。

Cのような言語に言及しました。C、C ++、またはJavaには話せませんが、C#には話せます。文字通りあなたの腕より長いC#のユーザー提案機能のリストがあります。私の知る限り、C#チームにそのようなオペレーターを提案したユーザーはいません。そのリストを何度も何度も調べました。

ある言語では存在し、使用されておらず、別の言語では決して要求されない機能は、それを最新のプログラミング言語にする可能性が低いです。特に、人々望む機能を作成するのに十分な時間と労力と予算が予算にない場合。


IMPはGWBASIC時代にオペレーターとして戻りました。1979
。– zarchasmpgmr

1
IMPLはコードコントラクトに非常に役立つことを読みました。(VBにはありませんでした。)
メイソンウィーラー

3
VBScriptプログラマは、おそらくこのような演算子を使用する可能性が最も低いグループでした。PowerShellには、暗黙的に演算子があり、いくつかの[switch]フィルターパラメーターをより簡単かつ読みやすく実装できることを望んでいます。
ブリアナリー

DEC BASICのIMPを覚えています。覚えていないEQV。私がしばしば望んでいた演算子は「否定」であり、右演算子否定する前に昇格させます。したがって、0xABCD12345678ul ~& 0x00200000u0x12145678ulではなく0xABCD12145678ulが生成されます。
-supercat

19

私は推測することしかできませんが、理由は非常にシンプルで読みやすい回避策があるかもしれません。あなたの例を考えてみましょう:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

式が必要な場合は、ほとんどの言語で使用可能なインラインif演算子(三項演算子と呼ばれることが多い)を使用できます。確かに、これはほどエレガントではありませんA --> Bが、ユースケースの数が別の演算子の追加(および保守)を正当化できない場合があります。

assert (mode != ECB ? iv != null : true);

2
主張の時点で-正当な理由があります。最初のメッセージは(多くの実装で)メッセージ「アサーションエラー:iv!= null」を生成し、2番目のメッセージは「アサーションエラー:モード!= ECB-> iv!= null」を生成します。
マチェイピエチョトカ

2
+1、私は質問でこれと同じことを聞こうとしていました(「含意」にあまり詳しくないので、毎日出てくることはありません)。このif声明は、ほぼ全員にとってはるかに明確です。
イズカタ

12

エッフェルには意味があります

実際にはさらに多くのものがあります。いくつかの半厳密な演算子と厳密な演算子があります。

プログラマーがそのようなものを使用しない理由は、彼らが何であるか、どのように使用するか、いつ使用するか、そしてそれらを使用して設計する方法を正確に知るように訓練されていないためです。彼らは決して訓練されていないので、彼らはコンパイラの作者からそれを決して要求しません。そのため、コンパイラの人々はコンパイラにそのようなメカニズムを置くことを気にしません。コンピューターサイエンスの学生とシェードツリープログラマーがより包括的な教育を受け始めると、コンパイラーが追いつき始めます。

このようなブール演算子を使用した言語を作成し、それを使用して設計および使用する方法を知ったら、それを使用することがわかります。

エッフェルでは、「アプライ」キーワードの使用がかなり重要です。これは、契約アサーションのブールが重い性質による契約ごとの設計のためです。「暗黙」演算子でのみ適切かつ効率的に記述できる契約がいくつかあります。そして、これは、契約のない言語は、含意の使用を見て、訓練し、実装する理由もなく、さらに進んでいるというコメントを頼みます。

これに加えて、ほとんどのプログラマーは「数学と論理の弱点」であり、ストーリーの残りの部分を教えてくれます。あなたが教育において数学と論理に精通している場合でも、含意などの構造を実装しない言語を選択すると、そのようなことは不要であるか役に立たないと考える傾向があります。言語に疑問を投げかけることはめったにありません。「コンパイラーの人には必要性がわからない」と「プログラマーには必要性がわからない」-無限の悪循環です。

代わりに、コンパイラーの人々は、理論にバックアップし、プログラマーの無洗浄の大衆が何を考えているか、何を求めているかに関係なく、理論によって示唆または暗示される言語表記(例えば、オブジェクト指向理論)を書く必要があります。そこから、教授、教師、およびその他の専門家は、「言語レンズによる理論」ではなく、生の理論に基づいて若いマッシュマインドを巧みに訓練する必要があります。これが起こると、人々は突然目を覚まし、何が欠けていて、何が自分に強要されているかを認識します。

現在、非常に多くの理論が存在しており、オブジェクト指向のように見せかけていますが、オブジェクト指向の「ガラスを暗くする」「言語を選ぶ」に過ぎません。OOのほとんどの「理論」の本を読むことはできません。なぜなら、彼らはある言語のレンズを通して理論が何であるかを解釈したいからです。完全に間違っていて間違っています。それは私の計算機に基づいた数学やスライドルールを教えるようなものです。いいえ-現実に自分自身について教えることを許可し、その後、表記を使用して、観察することを説明します。これは「科学」と呼ばれます。OO-based-on-language-Xと呼ばれるこの他のマッシュは、現実をかろうじて表すほど歪んでいます。

だから、言語から離れて、生の理論を見て、もう一度始めてください。言語の制限、制約、ペイントジョブに理論が何であるかを教えてはいけません。理論の現実に独自の表記法を指示させ、そこから言語の定式化に移ります。

そこから、どのように含意と「暗示」が有用であるだけでなく、エレガントで非常にクールであるかを取得し始めます!

素晴らしいものを!


7

Pythonには、ある種の隠された方法で含意演算子があります。

小なり演算子は、ブール値を受け入れるためにオーバーロードされます。その結果、含意演算子として使用できます。

例による証明(Pythonコード):

print (False <= False) # This will print True.
print (False <= True)  # This will print True.
print (True <= False)  # This will print False.
print (True <= True)   # This will print True.

含意演算子の真理値表は次のとおりです。

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T

2
これは素晴らしいですが、残念ながら間違った厳密性のプロパティがあります:isの場合はf() implies g()評価すべきではありませんが、この場合は評価します。g()f()False<=g()
ジョンパーディ14

2
@Jon Purdy-厳密に言えば、短絡評価は二項演算子のオプション機能です。技術的には、これは含意演算子の完全に正当な実装です。そうは言っても、Guido van Rossumがこれを含意演算子とすることさえ意図していたことは本当に疑わしい。これは、ブール値を比較するだけの癖です。
マッケンジー14

確かに、私はそれが興味深い観察であると言っていましたが、実際のプログラムで使用すべきではありません。短絡ではなくdid_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff())、動作を期待している人を驚かせる可能性があるからです。
ジョンパーディ14

2
これは、CおよびC ++でも機能します。
ベンフォークト

5

エッフェルには「暗黙」演算子があり、事前条件と事後条件を書くのに非常に便利です。残念ながら、Cのような言語の基本的な意図ではないコードを読みやすくし、エッフェルを使用する人が少なすぎるため、演算子としての「暗黙」の美しさはあまり知られていません。


2

私にとって、暗黙の問題は、初期条件が偽の場合に発生します。たとえば、「太陽が緑の場合、私はフルーツバットです。」本当だ!

正式なロジックでは、含意の条件が満たされない場合に値に「True」を割り当てるように機能します。しかし、プログラミングでは、直感に反する驚くべき結果につながる可能性があります。

実際、@ Heinziが上記の例を示していると思います。

if (sun.color() == "green") then assert(me.species() == "fruitbat")

理解しやすく、ロジックの誤解によるエラーが発生しにくい。

テストのコンテキストでは、仮定が間違った瞬間に停止します。

assert(sun.color() == "green")
assert(me.species() == "fruitbat")

それで、@ Eric Lippertのポイントに、プログラマーとして、私が含意演算子をいつ使用するかわかりません。「False is True」動作は、数学的形式論理のコンテキストでは有用に思えますが、プログラム論理で予期しない結果を招く可能性があります。

...

一般的な「?」については誰も言及していません。ここで、「A?B:true」は「implies」と同じです。しかし、正式なロジックは「else」条件にtrueを割り当てますが、「?」開発者が明示的に割り当てることができます。

フォーマルロジックでは「true」を使用するとうまくいきますが、プログラミングでは、条件がfalseの場合、より良い答えは「null」、「void」、または「skip」、あるいは場合によってはfalseです。

「暗黙」が「?」、「if」ステートメント、または単なる通常のプログラムフローよりも有用な演算子である理由を誰かが主張しなければならないと思う。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.