Obligatory digraphs/trigraphs reference: https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C
I think the whole idea of pre-pending ! to negate is a poor idea in general, it's too hard to spot especially in long convoluted lines where it's just thrown in before a complex bracketed expression.
It's brain training - you find "!" hard to spot, and I don't. And vice versa for ligatures. Thank goodness we both have choices!
Apparently it's a way to negate and convert to boolean.
(eta: didn't finish the thought - I'd assume SQL influenced Excel, since it's older.)
This is a much more readable cast.
The problem is that many developers are unaware that `const s = new String(x);` creates a string Object. It looks like a string, and acts like a string, except that in some places it is not a string: for example `typeof s` returns “object”! Same problem for Boolean, Number, etcetera. Yes casts are ok, but it is easier to just say never use the value object keywords because you can end up with very wierd bugs a long way from where the value object was created.
Another example:
let x = new Boolean(true);
console.log(x === true);
Gives false.if ( ! isLast(e) ) reads perfectly, especially since my native language doesn't insert the "not" im the middle like english does and my brain is used to that. if (isLast(e) == false) just jolts me out of that state where code reads as fluently as text. YMMV, of course, and I have a suspicion that your native language might play a role in that...
(edit) I'll additionally qualify my comment, from a mathematics background I can casually scan a handwritten "!=" which is the same as the ligature, but I just cannot retrain my adult brain to accept the ligature version which is the same as the handwritten one. Brain plasticity I suppose.