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
}
15
  • 12
    No, because we already have or and !, and because double negatives are rarely used - most people find them especially hard to read. Feb 6, 2018 at 7: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 6, 2018 at 8: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 6, 2018 at 9:24
  • 9
    @Troyer Your comment demonstrates the problem: you got the logic wrong. ;) That isn't equivalent to a nor.
    – jpmc26
    Feb 6, 2018 at 17:16
  • 3
    In languages with more operators, this would be (for example, in python) color not in ['green', 'blue']
    – Izkata
    Feb 6, 2018 at 19:13

7 Answers 7

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.

10
  • 41
    APL is not a golfing language, but rather an array-oriented language which allows interactive development of full-stack multi-paradigm applications with industrial strength.
    – Adám
    Feb 6, 2018 at 12:12
  • 59
    @Adám: Bingo. Feb 6, 2018 at 12:42
  • 6
    @EricDuminil :-) It is all true though.
    – Adám
    Feb 6, 2018 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 6, 2018 at 15:35
  • 14
    OP didn't actually say that APL was a “golfing” language, btw. Feb 7, 2018 at 1: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.

14
  • 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 6, 2018 at 9:06
  • 1
    @Baldrickk can you elaborate? Feb 6, 2018 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 6, 2018 at 11:08
  • 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 6, 2018 at 12:24
  • 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 6, 2018 at 16:23
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.

8
  • 4
    The redundancies could also be not needed or wanted :)
    – Dave
    Feb 6, 2018 at 10:33
  • @Dave That pun was intended, glad to see you noticed ;-)
    – Mael
    Feb 6, 2018 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. Feb 6, 2018 at 13:34
  • 1
    @KonradRudolph Technically, all you need is a lambda operator. 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 6, 2018 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 7, 2018 at 14:30
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!

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).

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.

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) {

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