70

It might be a strange question, but why there is no implication as a logical operator in many languages (Java, C, C++, Python Haskell - although as last one have user defined operators its trivial to add it)? I find logical implication much clearer to write (particularly in asserts or assert-like expressions) then negation with 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
}
16
  • 31
    Because it wasn't put in C; if it have been put then C++, Java and C# would have had it.
    – Random42
    Jan 18, 2013 at 13:17
  • 4
    But C doesn't have it, in turn, because it's not a common part of assembly language. Whereas as all instruction sets I know of include and, or and not, I know of none that include implies - no doubt someone will be along to tell me of some obscure instruction set that does shortly... Jan 18, 2013 at 14:30
  • 4
    Maybe it was considered redundant because (1) it is less primitive than "^", "v", "~", (2) it saves very little typing since "A => B" is equivalent to "~A v B".
    – Giorgio
    Jan 18, 2013 at 14:50
  • 5
    Languages that deal with logical constructions are more likely to have it. Chiefly among these is prolog
    – user40980
    Jan 18, 2013 at 15:22
  • 10
    I'm surprised that you think assert #1 is clearer than #2. I have stared at #1 for some time and still can't see how it's behaviour could be considered intuitive. (especially with the extra != flipping the logic) Feb 14, 2013 at 16:07

9 Answers 9

63

It could be useful to have sometimes, no doubt. Several points argue against such an operator:

  • The characters - and > are valuable, both in isolation and combined. Many languages already use them to mean other things. (And many can't use unicode character sets for their syntax.)
  • Implication is very counter-intuitive, even to logic-minded people such as programmers. The fact that three out of the four truth table entries are true surprises many people.
  • All other logical operators are symmetrical, which would make -> an exception to orthogonality.
  • At the same time, there is an easy workaround: use operators ! and ||.
  • Implication is used vastly less often than logical and/or.

This is probably why the operator is rare today. Certainly it could become more common, as new dynamic languages use Unicode for everything and operator overloading becomes more fashionable again.

14
  • 23
    Your first point only argues against using '-->' as the symbol for the operator, not against actually having the operator. The others are good points.
    – AShelly
    Jan 18, 2013 at 14:21
  • 16
    "At the same time, there is an easy workaround: use ! and &&.": In fact, the simplest way of simulating "->" (or "=>", as it is more common in Math), is to use ! and ||, not ! and &&: A -> B is equivalent to !A || B which is equivalent to !(A && !B).
    – Giorgio
    Jan 18, 2013 at 14:53
  • 27
    "The fact that three out of the four truth table entries are true surprises many people." Wat. I know another operator with the same feature which is used rather often...
    – l0b0
    Jan 18, 2013 at 18:09
  • 10
    @l0b0, I'm a programmer who studied CS, but it was a long time ago. I had forgotten that "implies" is a formal operation with two operands that returns a truth value, so at first I was confused at the nature of this question. In everyday speech, I only ever use "implies" when the first operand is already known to be true ("X is true, so Y must be true"). After a minute, I remembered how formal "implies" works, but the fact remains -- even for someone who once did study formal logic, the intent was not clear to me. And if I had never studied it, it wouldn't have even eventually made sense.
    – Ben Lee
    Jan 22, 2013 at 20:54
  • 8
    (a) In C -> is used as an operator. No one complains about that. I would use => anyway. (b) Counter-intuitive to whom? The definition of implication is just that, a definition. (c) subtraction is not commutative. No one complains about that. (d) I think you mean ! and ||. Because of precedence ( and ) are often also needed. The same argument could be used against && or ||; take your pick. (e) Perhaps that is because it is not in most languages. Many uses of || could be concisely and (to me at least) intuitively replaced by implication. Sep 15, 2013 at 20:30
55

I believe the answer lies in the mathematical foundations. Implication is usually considered and defined as a derived, not elementary, operation of boolean algebras. Programming languages follow this convention.

This is Proposition I of Chapter II from George Boole's An Investigation of the Laws of Thought (1854):

All the operations of Language, as an instrument of reasoning, may be conducted by a system of signs composed of the following elements, viz.:

1st. Literal symbols, as x, y, &c., representing things as subjects of our conceptions.

2nd. Signs of operation, as +, −, ×, standing for those operations of the mind by which the conceptions of things are combined or resolved so as to form new conceptions involving the same elements.

3rd. The sign of identity, =.

And these symbols of Logic are in their use subject to definite laws, partly agreeing with and partly differing from the laws of the corresponding symbols in the science of Algebra.

Boole's sign + represents the same "operation of the mind" we today recognize as both the boolean ´or´ and the union of sets. Similarly the signs − and × correspond to our boolean negation, complement of a set, boolean ´and´ and intersection of sets.

13
  • +1 - solid answer. Boolean algebra and the simplifications in logic that it allows drives a lot of programming methodology. Using an "implies ..." would potentially interfere with "don't care" conditions.
    – user53019
    Jan 18, 2013 at 14:34
  • 3
    1. That depend on definition. It is possible to define or as a || b = !(!a && !b) (I met or as derived operator in logic). 2. The reason why it is done is usually to simplify induction proves I believe (we know that derived operators are just short-cuts so we don't need to have separate case for them). @GlenH7: What "don't care" conditions? a --> b is the same as !a || b. Jan 18, 2013 at 14:55
  • 4
    Also - we have other derived operators like xor (!=) nxor (==)... Jan 18, 2013 at 14:57
  • 6
    Actually, you can derive everything from either NAND !(a && b) or NOR !(a || b). For example, NOT a == a NAND a, a AND b == NOT(a NAND b), a OR b == (NOT a) NAND (NOT b). But providing only a NAND operator puts you in the realm of esoteric languages (which fits surprisingly well, given the answerer's username ;-) ). Jan 18, 2013 at 22:17
  • 1
    @Stefan: You can also derive everything from an IMPL. May 1, 2014 at 15:15
39

UPDATE: This question was the subject of my blog in November 2015. Thanks for the interesting question!


Visual Basic 6 (and VBScript) had Imp and Eqv operators. No one used them. Both were removed in VB.NET; to my knowledge, no one complained.

I worked on the Visual Basic compiler team (as an intern) for a full year and never once noticed that VB even had those operators. Had I not been the guy writing the VBScript compiler, and therefore had to test their implementations, I probably would not have noticed them. If the guy on the compiler team doesn't know about the feature and doesn't use it, that tells you something about the popularity and usefulness of the feature.

You mentioned C-like languages. I can't speak to C or C++ or Java but I can speak to C#. There is a list of user-suggested features for C# literally longer than your arm. To my knowledge, no user has ever proposed such an operator to the C# team, and I've gone over that list many, many times.

Features that exist and are unused in one language, and are never requested in another are unlikely candidates to make it into modern programming languages. Particularly when there is not enough time and effort and money available in the budget to make features that people do want.

4
  • 1
    IMP goes back as an operator to GWBASIC days. I remember it from 1979. Jan 21, 2013 at 21:15
  • 2
    I've read that IMPL is very helpful for code contracts. (Which VB didn't have.) May 2, 2014 at 15:19
  • 4
    VBScript programmers were probably the group least likely to use such an operator. I'm wishing right now that PowerShell had an implies operator so I could more easily & legibly implement some [switch] filter parameters.
    – brianary
    Jun 12, 2015 at 22:46
  • I remember IMP from DEC BASIC. I don't remember EQV. The operator I've often wished for would be "and not", which would promote the right-hand operator before negating it. Thus, 0xABCD12345678ul ~& 0x00200000u would yield 0xABCD12145678ul rather than 0x12145678ul.
    – supercat
    Jul 25, 2015 at 21:24
21

I can only guess, but a reason might be that there are workarounds which are quite simple and readable. Let's consider your example:

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

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

If you need an expression, the inline-if operator available in most languages (often called the ternary operator) can be used. Granted, this is not as elegant as A --> B, but the number of use cases might not justify adding (and maintaining!) another operator:

assert (mode != ECB ? iv != null : true);
2
  • 2
    As of asserts - there is good reason. First one will produce (in many implementations) message "assertion failure: iv != null" while second "assertion failure: mode != ECB --> iv != null". Jan 18, 2013 at 14:56
  • 2
    +1, I was about to ask this same thing on the question (since I'm not very familiar with "implication", it never comes up day-to-day). The if statement is far, far clearer to just about everyone.
    – Izkata
    Jan 18, 2013 at 19:16
17

Eiffel has Implication

It actually has even more. It has a number of semi-strict operators as well as strict.

The reason programmers do not use such things is because they are never trained to know precisely what they are, how to use them, and when to use them -- as well as how to design with them. Because they are never trained, they never ask for it from the compiler writers, which is why the compiler people do not bother putting such mechanisms in the compiler. When Computer Science students and Shade-tree programmers begin getting a more rounded education, then the compilers will start catching up.

It turns out that once you have a language with such Boolean operators and you know how to design with them and use them, then you use them.

In Eiffel the use of the "implies" keyword is rather prominent because of Design-by-Contract due to the Boolean-heavy nature of contract assertions. There are some contracts that can only be written properly and efficiently with the "implies" operator. This then begs the comment that languages without contracts are further without cause to look at, train, and implement the use of implication.

Add to this that most programmers are "math-and-logic-weak" tells us the remainder of the story. Even if you are math-and-logic-heavy in your education, when one chooses a language that does not implement constructs such as implication, then one tends to think such things are unnecessary or not useful. One rarely questions the language and gets into an echo-chamber of: "Well the compiler guys don't see the need" and "Well the programmers don't see the need" -- endless and vicious circle.

Instead, the compiler people need to back up to the theory, write a language notation that is suggested or implied by the theory (e.g. Object Oriented Theory) regardless of what the unwashed masses of programmers think or ask for. From there, professors, teachers, and other professionals need to expertly train young mush-minds based on raw theory and NOT "theory-through-the-language-lens". When this happens, people will suddenly wake up and realize what they have been missing and what has been foisted on them.

Right now -- there is so much theory out there that masquerades as Object Oriented, but is just O-O-through-a-glass-darkly-of-[pick-your-language]. One cannot read most "theory" books on O-O because they want to interpret what the theory is through the lens of some language. Totally false and incorrect. It would be like teaching math-based-on-my-calculator or my slide rule. NO -- one allows reality to teach one about itself and then uses a notation to describe what one observes -- that's called "science". This other mash called O-O-based-on-language-X is so skewed as to barely represent reality.

So, step away from the language, take a look at raw theory, and begin again. Do not let limitations, constraints, and paint-jobs of a language tell you what the theory is. Simply let the reality of the theory dictate its own notation and then move from there into formulating a language.

From there, you will start to get how implication and "implies" is not only useful, but elegant and very cool!

Have a great one!

8

Python has an implication operator in a sort of hidden way.

The less-than-or-equals operator is overloaded to accept boolean values. As a result, one can use it as an implication operator.

Proof by Example (Python Code):

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.

Recall the truth table of the implication operator is:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T
4
  • 3
    This is awesome, but unfortunately has the wrong strictness properties: f() implies g() should not evaluate g() if f() is False, but <= does evaluate g() in this case.
    – Jon Purdy
    Jul 30, 2014 at 7:26
  • 3
    @Jon Purdy - Strictly speaking, short-circuit evaluation is an optional feature of binary operators. So technically, this is a perfectly legitimate implementation of the implication-operator. That being said, I really doubt that Guido van Rossum even intended this to be an implication-operator. This is just a quirk of comparing booleans.
    – Mackenzie
    Aug 1, 2014 at 20:38
  • Sure, I was saying it’s an interesting observation, but not something you should use in real programs because it isn’t short-circuiting and that could take somebody by surprise if they expected did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff()) to work.
    – Jon Purdy
    Aug 1, 2014 at 21:09
  • 2
    This works in C and C++ as well.
    – Ben Voigt
    Oct 2, 2015 at 3:25
5

Eiffel has an "implies" operator and it is very nice for writting pre- and postconditions. It makes code more readable, unfortunately that was never a fundamental intension for C like language and too few people used eiffel so the beauty of "implies" as operator is not well known.

3

For me, the big problem with implies comes when the initial condition is false; for example: "If the sun is green, then I am a fruit bat." True!

In formal logic it just works to assign "True" to the value when the condition of the implication isn't met. But in programming, that could lead to counter-intuitive and surprising results.

I actually think the example @Heinzi gives above:

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

Is much easier to understand, and less prone to errors due to misunderstanding the logic.

In the context of testing, I'd just halt the moment my assumptions became false:

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

So, to @Eric Lippert's point, as a programmer I don't know when I'd use an implies operator. The "False is True" behavior seems useful in the context of mathematical, formal logic, but could lead to unexpected results in program logic.

...

No one has mentioned the common "?" operator, where "A ? B : true" is the same as "implies". But while formal logic assigns true to the "else" condition, "?" lets the developer assign that explicitly.

In formal logic, using "true" works out, but in programming, if the condition is false, then the better answer is more like "null" or "void" or "skip", or even maybe false.

I think someone would have to make the case why "implies" is a more useful operator than "?", or "if" statements, or just regular program flow.

1

Racket has implies. It macro-expands to an if expression.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.