57

Is there an operator equivalent of nor? For example, my favorite color is neither green nor blue.

And the code would be equivalent to:

// example one
if (color!="green" && color!="blue") { 

}

// example two
if (x nor y) {
    // x is false and y is false
}
Taegost
  • 103
  • 3
1.21 gigawatts
  • 1,209
  • 1
  • 10
  • 22
  • 12
    No, because we already have `or` and `!`, and because double negatives are rarely used - most people find them especially hard to read. – Kilian Foth Feb 06 '18 at 07:57
  • 71
    @KilianFoth is right. Nevertheless downvotes should be for bad questions, not for questions we don't like. Furthermore, there are already three votes to close the question because it would be "opinion based", despite the question being totally neutral and non controversial (either there are such operators in some exotic language or there are't). – Christophe Feb 06 '18 at 08:29
  • 3
    Is there a name for it? Yes: nor. Is it an operator? In what language? And given a language, you could look that up in the spec/docs. – jonrsharpe Feb 06 '18 at 09:24
  • 1
    @1.21gigawatts: I think the downvotes is because of the title can be read as "is there a name for the definition of *nor*?" which is a silly question. But asking whether any language have a nor-operator is a legitimate question. – JacquesB Feb 06 '18 at 10:17
  • 1
    What is wrong about negating all the if condition ? `if(!(color!="green" && color!="blue"))` – Troyer Feb 06 '18 at 14:29
  • 1
    @KilianFoth "Double negative" does not refer to a logical nor. It's a language term; it refers to applying an extra negative (some form of "not") to a verb when the object of the verb is already negative, e.g. "I didn't say nothing." – jpmc26 Feb 06 '18 at 17:13
  • 9
    @Troyer Your comment demonstrates the problem: you got the logic wrong. ;) That isn't equivalent to a nor. – jpmc26 Feb 06 '18 at 17:16
  • 3
    In languages with more operators, this would be (for example, in python) `color not in ['green', 'blue']` – Izkata Feb 06 '18 at 19:13
  • The second one (also in python) could be `not any([x, y])` – Izkata Feb 06 '18 at 19:19
  • (Basically, the two are conceptually different: A series of comparisons vs a set of true/false) – Izkata Feb 06 '18 at 19:28
  • If someone actually makes something like this, I think they should make a broader operator (I'll represent it as `$`) that allows for such as this: `x!=5$4$8`, which means you could also use other operators besides `!=` to be repeated. – Brōtsyorfuzthrāx Feb 07 '18 at 05:22
  • Of course, you could make a precompile script to exchange your own symbol with the desired repetition, which would be `x!=5 and x!=4 and x!=8` in my example above. – Brōtsyorfuzthrāx Feb 07 '18 at 05:30
  • 1
    4 "primarily opinion based" close votes for a question that is *definitely* not opinion based? WTF? That is one of those cases were I really wish there were a ["keep open" close vote option](https://meta.stackoverflow.com/questions/298520/directly-vote-to-not-close-a-question). – Heinzi Feb 07 '18 at 07:51
  • Nor is clearly a bad name, it should be Neither. – James Feb 07 '18 at 18:47
  • In languages where custom operators can be defined, like Haskell, Scala, or Standard ML/Ocaml, this is certainly possible. – Alex Reinking Feb 07 '18 at 19:44

7 Answers7

71

Although mainstream languages do not have dedicated NOR and NAND operators, some lesser-known languages (for example, some "golfing" languages) do. For example, APL has and for NOR and NAND, respectively.

Another class of examples can be found in hardware design languages such as VHDL, Verilog, etc. NAND and NOR gates are quite useful in hardware design due to usually being cheaper (requiring fewer transistors) than the equivalent circuit made from AND/OR/NOT gates, which is one of the reasons hardware design languages tend to include them; another reason is that they can be useful for certain bit-fiddling tricks.

nomadictype
  • 1,632
  • 1
  • 11
  • 7
  • 1
    Good catch about NAND and NOR being present in hardware description languages! – Mael Feb 06 '18 at 11:16
  • 1
    Caveat: the reason given here for the inclusion of NAND and NOR in HDL languages is no longer relevant. Modern ASIC design uses standard libraries where the number of transistors has no 1-1 relationship with the area anymore. As such the reason NAND and NOR are part of the language is mainly historical since the reasons given here used to be true. – DonFusili Feb 06 '18 at 11:31
  • 41
    APL is not a [golfing language](https://en.wikipedia.org/wiki/Code_golf#Dedicated_golfing_languages), but rather an array-oriented language which allows interactive development of full-stack multi-paradigm applications with industrial strength. – Adám Feb 06 '18 at 12:12
  • 59
    @Adám: [Bingo](http://dilbert.com/strip/1994-02-22). – Eric Duminil Feb 06 '18 at 12:42
  • 6
    @EricDuminil :-) It is all true though. – Adám Feb 06 '18 at 12:45
  • 20
    @EricDuminil No, really. APL is not a golfing language, it's a practical language that happens to be good at golfing. Perl is similar in this regard, no? – Pavel Feb 06 '18 at 15:35
  • 2
    And I don't think that the two successive "for example" clauses ever claimed to be the same example. – Toby Speight Feb 06 '18 at 15:54
  • 3
    @Pavel Being a practical language and a golfing language isn't mutually exclusive. I've seen people successfully golf with Python. – candied_orange Feb 06 '18 at 16:21
  • 2
    @CandiedOrange Of course you have! I golf in Python and Ruby and C# myself. But they weren't *made* for golfing. – Pavel Feb 06 '18 at 17:40
  • 14
    OP didn't actually say that APL was a “golfing” language, btw. – Will Crawford Feb 07 '18 at 01:04
45

No, there is no nor operator in any high level mainstream programming language.

Why ?

Mainly because it is difficult to read:

  • it requires the mental combination of several operators ( "and not", or in a more literary style : "further negative", "each untrue")
  • it implies an implicit not on the first operand, but the reader only understand this afterwards
  • it is different from human languages, which use an explicit negation on the first operand, such as "neither x nor y", "nor x nor y". So a reader might confuse (x nor y) with (x and not y) instead of ((not x) and (not y))
  • some readers are confused with the apparent or semantic which doesn't apply

But it's so common in hardware...

nor is an elementary hardware gate that can be used to make all the other logical gates. So one could argue that all the other logical operators are combinations and nor is the simplest elementary logical operator.

However, what's true for the hardware is not necessarily true to the humans. And despite it's popularity at hardware level, some mainstream CPUs do not even offer a NOR in their assembler instruction set (e.g. x86).

Alternatives

Readability matters. And sometimes it can be improved by other means.

Use of existing operators

For example:

if x not in [1,2]    // use of 'in' or 'not in' operator instead of x!=1 and x!=2

Ordering of conditions

if x==1 or x==2 
     action A
else 
     action B  

instead of

if x!=1 and x!=2 
    action B
else 
    action A

Use of until loop

Some languages also offer loop instructions that allow to express conditions either with while or with until, letting you choose the more "positive" way. These instructions are for example until c do ... in ruby, do until c ... in vb, or repeat ... until c in pascal and its descendants.

For example:

Until (x==1 or x==2) do
     ...

is equivalent to:

While (x!=1 and x!=2)
    ...

Make a function

Now if you still prefer the nor syntax, you could define a function, but only if you don't expect a shortcut to happen:

If ( nor(x,y) )   // attention, x and y will always be evaluated
    ...  

There is a readability advantage of the function over the operator, because the reader immediately understands that the negation applies to all arguments. In some languages you can define a function with a variable number of arguments.

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 5
    Funny, I usually write that as `while (not (x == 1 or x == 2))` as I find the `x != 1 and x != 2` version hard to read, and find "x is neither 1, nor 2" much easier to process than "x is not 1, and x is not 2". – Mael Feb 06 '18 at 09:06
  • Those two loops are not equivalent... – Baldrickk Feb 06 '18 at 10:47
  • 1
    @Baldrickk can you elaborate? – HopefullyHelpful Feb 06 '18 at 11:02
  • 4
    @HopefullyHelpful `Repeat`... `Until` always executes the loop body at least once. If x is 1, the loop body is still executed, but not repeated. The `While` loop won't execute the body in this case. – sina Feb 06 '18 at 11:08
  • @HopefullyHelpful I was leaving that as a simple exercise to the reader ;) As sina says, the first one executes the body at least once, but the while may not execute the body at all. To make them equivalent, you need to test the condition prior to entering the first loop. – Baldrickk Feb 06 '18 at 11:13
  • 2
    @Baldrickk yes you are completely right. When I write equivalent, I was only speaking about the loop condition, as the boolean operators were the subject of the question. Thank you, i'll reword it to clarify – Christophe Feb 06 '18 at 12:24
  • @Mael interesting! For me it really depends on the intent and the meaning of the terms being logically connected. Set operation could also help to make it readable when available (e.g. python's ’x in [1,2,8]’ and ’x not in [1,2]’). However the question seems more general, as it's not only about == and != but also > and <= as well as any other boolean condition – Christophe Feb 06 '18 at 13:11
  • 1
    FWIW NOR is not the "combination of several operators"; it's a basic logical operator like the others: https://en.wikipedia.org/wiki/Logical_NOR "The computer used in the spacecraft that first carried humans to the moon, the Apollo Guidance Computer, was constructed entirely using NOR gates with three inputs." – user1936 Feb 06 '18 at 14:39
  • @Mael, except that "x is neither 1 or 2" has the same meaning no? so in essence your qualm could be be settled with a niether function or operator, rather than a nor operator, eg `if(x is neither a, b, c..)`, and then at that point, you might as well just use not. `if(x is not a, b, c)` and for better parsing for python (knowing when the statement ends better) `if x is not a, b, or c:` and you could similarly do if `x is a, b or c:`. Really what your asking for isn't nor, but better logic syntax with the same symbols we currently use. – Krupip Feb 06 '18 at 16:18
  • 3
    Wether x and y in `nor(x,y)` are always evaluated depends on the language and how `nor()` is implemented. There are languages (D, Io, …) where the called function can decide if and when to evaluate arguments. – BlackJack Feb 06 '18 at 16:23
  • 1
    @user1936 fair point: NOR is an elementary HW gate that is used to make all the other gates. But strictly speaking, this kind of NOR is not a logical operator but an [gate implementing](https://en.m.wikipedia.org/wiki/NOR_gate) the behavior of the logical operator. I also agree that NOR can be defined directly by its truth table. For a human brain however, NOR is still the combination of AND NOT (or in more literary style: ["further negative", "each untrue"](https://en.oxforddictionaries.com/definition/nor)). X86 assembler also [doesn't know NOR](http://www.felixcloutier.com/x86/index.xml) – Christophe Feb 06 '18 at 16:47
  • I'm not sure that "nor" would be useful, but in many contexts "and not" would be helpful in cases where it's necessary to clear a specified set of bits in a value. Something like `uint64a = uint64b & ~0x40000000;` will work to clear one bit, but `uint64a = uint64b & ~0x80000000;` may clear all of the top 33 bits. A proper "and not" operator would not have such a problem. Incidentally, the ARM instruction set has an "and not" instruction, called "bic" [bit clear]. – supercat Feb 06 '18 at 19:50
  • @supercat interesting thoughts ! ARM has also an ORN instruction (which is another name for NOR). This raises the question of bitwise NOR vs. logical NOR – Christophe Feb 06 '18 at 20:15
  • @Christophe: I think ORN is "OR NOT, isn't it? I can't think of many cases where ORN would be useful; it's more likely part of the instruction set because so many other instructions have complement forms that making "OR" do otherwise would have required more work. The thing about BIC is that it's used a lot; probably more than "AND" in cases where the resulting value will be of interest (as opposed to code just wanting to know if the result is zero). – supercat Feb 06 '18 at 21:28
18

@KilianFoth's comment on the question is spot on.

You can synthesize nor from not and or:

if (x nor y)

is exactly the same as

if (not (x or y))

Introducing nor as a separate operator would introduce redundancies to the language, which are neither needed, nor wanted (or - which are not needed and not wanted).

Similarly, I am not aware of any language having a nand operator - probably because it can be synthesized from not and and operators.

You could, in theory, create a language with only nand or only nor operators. All of and, or, and not could then by synthesied from them. The only problem is that this would be ridiculously unwieldy. For examples, see NOR logic and NAND logic on Wikipedia.

Mael
  • 2,305
  • 1
  • 13
  • 26
  • 4
    The redundancies could also be not needed or wanted :) – Dave Feb 06 '18 at 10:33
  • @Dave That pun was intended, glad to see you noticed ;-) – Mael Feb 06 '18 at 11:18
  • 5
    Redundancies alone don’t really explain why `nor` isn’t included. Otherwise, why do languages have `and` and `or`? They’re redundant, thanks to De Morgan. In fact, you could substitute all three conventional logical operators (`and`, `or`, `not`) by providing *just* `nor`, as you rightly observed. – Konrad Rudolph Feb 06 '18 at 13:34
  • @KonradRudolph Good question, actually... I'd say because people are accustomed to having `and`, `or`, and `not` available, and it's easy to synthesize other operators if you have all of them. It was not immediately obvious to me how `and` can be synthesized `not` and `or`, and `or` from `not` and `and`. – Mael Feb 06 '18 at 14:19
  • 1
    @KonradRudolph Technically, all you need is [a lambda operator](https://en.wikipedia.org/wiki/Lambda_calculus). The reason we do more is to match the mental model most programmers have. Most programmers think of logic in terms of `and`, `or` and `not` -- because that's what most human languages use. Once you match the mental model of and/or/not, then nor & nand become redundant. Their redundancy is even encoded in their names: "n(ot )and" and "n(ot )or". If we had distinct, pre-existing English terms for them, and not just synthesized ones, then you'd probably see them more often. – R.M. Feb 06 '18 at 18:59
  • 1
    Re redundancy as argument: There are languages with more than `not`, `and`, `or`. For instance some BASIC dialects (GW-BASIC, QuickBASIC, …) have exclusive or XOR, implication IMP (→ NOT(x XOR y)), and equivalence EQV (→ NOT(x) OR y) as additional operators. – BlackJack Feb 07 '18 at 14:30
  • @BlackJack: I've not encountered much use for the operators you describe; the ones I've found lacking are "X and not Y" [with Y being promoted to X's type before the negation] and a ternary form of either "(X and not Z) xor Y", or "X xor ((X xor Y) and Z)" (each of the latter two is more useful than the other in some cases where (Y and not Z) is non-zero, but their biggest usefulness comes in cases where (Y and not Z) is zero and the two operations would be equivalent. – supercat Feb 07 '18 at 17:54
  • @R.M. Just to clarify, mine was a rhetorical question. I knew the reason; my point was that “redundancy” isn’t it. – Konrad Rudolph Feb 07 '18 at 18:06
11

Yes, APL and some of its dialects have nor (and nand). In APL, nor is denoted (since is or and ~ is not):

∇ result←ExampleOne color
  :If (color≡'green')⍱(color≡'blue')
      result←'warm'
  :Else
      result←'cold'
  :EndIf
∇

∇ result←ExampleTwo(x y)
  :If x⍱y
      result←'x is false and y is false'
  :Else
      result←'at least one of them is true'
  :EndIf
∇

Try it online!

Adám
  • 264
  • 1
  • 5
10

This answer is from the assembler language for a computer made in the mid 1960s. That's pretty obscure, but in some respects it addresses your question.

DEC (Digital Equipment Corporation) launched the PDP-6 computer in the mid 1960s. This machine had a total of 64 instructions that were boolean operations on two operands (including some degenerate cases). These 64 instructions were really 16 operators with 4 variants in each operator.

Two of the operators, ANDCB and ORCB implemented NOR and NAND respectively (unless I am mixed up on the double negative logic). You can see the opcode table. The opcode table is actually for the PDP-10 computer, a successor to the PDP-6.

If you look at the numerical instruction in binary, it gets more interesting. It turns out that for all the opcodes in the range 400-477 (octal), four bits in the instruction itself provide a four bit truth table for 16 possible boolean operators. Some of these operators ignore one or both of the inputs. For example SETZ and SETO ignore both of the inputs.

The designers of the PDP-6 exploited this fact to implement all these instructions with less logic than it would have taken to implement only some of them. Some of these instructions appeared rarely, if ever, in assembly language code. But they were all there.

So ANDCB is the equivalent of NOR. (again, unless I got my logic backwards, in which case ORCB is the equivalent).

Walter Mitty
  • 806
  • 5
  • 14
3

Perl has the unless keyword that lets you invert conditionals:

unless ($color eq 'green' or $color eq 'blue') {
    # code
}

While not NOR operator, you can express your intent in a similar way.

Rory Hunter
  • 1,737
  • 9
  • 15
3

The nor operator as you described it would not be repeatable, which is bound to lead to lots of difficult to spot bugs.

Your "Example 2" is essentially this:

if (false nor false) {
becomes
if (true) {

But try that again with three variables and see what happens:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Buh Buh
  • 293
  • 1
  • 3
  • 9