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 NANDs, 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
nandinstruction 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!