Why doesn't JavaScript have explicit words for logical operations?

Reasons for this question

  1. Python is a programming language that has a very interesting philosophy... Called The Zen of Python. On this, does Javascript have a philosophy just like Python... as The Zen of Javascript?
  2. In Python philosophy there is something like the law "Explicit is better than implicit." Why doesn't JavaScript have explicit words for logical operations? What is the philosophy behind javascript?
  3. My goal in this question is to know a curious fact ... my goal is not to criticize JavaScript ... but know which philosophy behind JavaScript ...
  4. I didn't eat information about it

Some examples...

case 1: or

case1.1: example1.js

alert( true || true );   // true
alert( false || true );  // true
alert( true || false );  // true
alert( false || false ); // false

case1.2: example2.js

alert( true or true );   // true
alert( false or true );  // true
alert( true or false );  // true
alert( false or false ); // false

case2.1: example1.js

result = a || b;

case2.2: example2.js

result = a or b;

case3.1: example1.js

if (1 || 0) { // works just like if( true || false )
  alert( 'truthy!' );
}

case3.2: example2.js

if (1 or 0) { // works just like if( true || false )
  alert( 'truthy!' );
}

case 2: and

case1.1: example1.js

alert( true && true );   // true
alert( false && true );  // false
alert( true && false );  // false
alert( false && false ); // false

case1.2: example2.js

alert( true and true );   // true
alert( false and true );  // false
alert( true and false );  // false
alert( false and false ); // false

case 3: not

case1.1: example1.js

alert( !true ); // false
alert( !0 ); // true

case1.2: example2.js

alert( not true ); // false
alert( not 0 ); // true

references

Because JavaScript's author decided to model its syntax after Java, which was the popular language of the time. (at least, that's how I remember the history, someone can correct me if I'm wrong or misinformed). At this time, most languages were using symbols instead of keywords for operators, so it makes sense that JavaScript followed this legacy, they didn't have a strong reason to deviate. Plus, it gives JavaScript a familiar feel for those coming from other languages. And, considering it was built in two weeks, it's probably better to follow the status quo, because you don't have time to try and invent new ideas.

So, both JavaScript and Java use || for "or", and && for "and". They both use ! for "not". They both have similar switch statements, and the same case-fallthrough pitfalls. The syntax looks identical for for-loops, ifs, whiles, etc. Of course, the actual language is very different from Java, but its syntax is pretty close.

Note that some of JavaScript's newer syntax deviates from these patterns a bit. "await", "yield", etc, are all keywords, they're not operators. But, we still use operator-based syntax as well, like with "??", but perhaps that's for the better, what keyword would you give to "??"? I can't think of any concise one.

5 Likes

The answer from Scotty addresses the question better, but here's my 2 cents:

Using symbols/signs rather than keywords is easier to implement, because they never collide with identifiers (vars, params, etc. so no special cases to check), and allow more identifier names to be valid (if new didn't exist you could do let new and it wouldn't be an error).

If it helps you can interpret them like this:

  • "&" reads as "and" in natural language, but because it already means "bitwise AND", we need a different operator. Next option? && "logical AND"
  • In natural lang, we would use a slash "/" as a "logical OR", but because it's a division-op, we need another option. Next? vertical bar |, the closest thing to a slash that isn't a backwards slash "\" (it already works as an escape-char, so we can't use it). Problem is, it already means "bitwise OR", so the next alternative is || ("//" is already a line comment).
  • There's no symbolic equivalent in natural lang for the word "not". The closest thing is arithmetic negation -x (unary minus), and we have ~ as "bitwise NOT", but ~~x is x|0, so we can't rely on run-length for this. == has a negated counterpart != (because it looks similar to "≠"). So what's the best choice? ! (bang)

As you can see, the path from "/" to "||" is much more convoluted, which makes it less readable than "or" and "&&", but it's the best alternative we have, and changing it now would break the entire web (unless we add aliases).

I committed a lot of fallacies there, because when designing a lang, you get to choose the order in which to define operators, to avoid collisions in the future. But JS didn't have such a luxury, because there was a deadline, unfortunately