I know that some languages like APL have a dedicated NAND
operator, but I'm thinking about languages like C, C++, Java, Rust, Go, Swift, Kotlin, even instruction sets, etc. since these are the languages which actually implement golfing languages.
As far as I know, modern processors are made up of NAND
gates, since any logic gate can be implemented as a combination of NAND
gates. For example, processors compose NAND
gates like this to create these operators:
A AND B == ( A NAND B ) NAND ( A NAND B )
A OR B == ( A NAND A ) NAND ( B NAND B )
NOT A == ( A NAND A )
So, it just makes sense to me that it would be really efficient for a program to say "Hey, I have a NAND
operation for you; please pass it through only one gate and store the result in a register." However, as far as I'm aware, no such operator exists in actual compiled languages.
I've seen arguments saying that these languages don't contain a dedicated NAND
operator since C = A NAND B
can be expressed as these:
C = NOT ( A AND B )
C = ( NOT A ) OR ( NOT B )
The problem I see is that, since each of these operators is implemented in the processor as a combination of NAND
s, then expressing NAND
as these compositions might have them be executed as this:
; C = NOT ( A AND B )
X = A NAND B
X = X NAND X
C = X NAND X
; alternatively:
C = ( ( A NAND B ) NAND ( A NAND B ) ) NAND ( ( A NAND B ) NAND ( A NAND B ) )
; C = ( NOT A ) OR ( NOT B )
X = A NAND A
Y = B NAND B
C = ( X NAND X ) NAND ( Y NAND Y )
; alternatively:
C = ( ( A NAND A ) NAND ( A NAND A ) ) NAND ( ( B NAND B ) NAND ( B NAND B ) )
This seems silly and inefficient to me! Just look at the first line of the implementation of C = NOT ( A AND B )
: it gives us the result right away! But we toss it back and forth a few times after that anyway to return to the result we started with.
I know each of these gates is a single processor instruction, but wouldn't that instruction be so much more efficient if it only passed through one gate rather than several?
I assume and pray that some compiler or something is smart enough to optimize this (after all, I see NAND
in some IBM instruction sets), but I haven't heard of higher-level languages having an operator that explicitly invokes it. My question is why not just let the dev specify "Here is a NAND
operation; just do that"?
--
Related:
- Why is there no
nand
instruction in modern CPUs? (about the circuits within a CPU, not languages) - Why do higher level languages have neither xor nor nand short-circuit operators? (about missing operators in general, not this specific one. Also about short-circuiting)
|
and&
- but unlike NAND, rotate is actually useful to programmers!