4 ms·
Fun fact -- in V8 this is the only case which requires three token lookahead, to distinguish `<!-foo` meaning "less-than not negative foo" from `<!--` meaning "
by Leszek 5y ago
Fun fact -- in V8 this is the only case which requires three token lookahead, to distinguish `<!-foo` meaning "less-than not negative foo" from `<!--` meaning "start of HTML comment". There's a whole rewinding mechanism in the scanner which wouldn't have to exist if not for this syntax.
- srcreigh 5y agoThat's extra funny considering `<!-foo` is an extraordinarily useless expression.
- eyelidlessness 5y agoIn useful code sure. But `<!-f` with its dynamic casting implications may be useful in code golf. I haven’t golfed in years so I’m not sure, but I can imagine it having some benefit I haven’t though of.
- srcreigh 5y agoYou may be right. Unless it's true that `<!-f` is always equivalent to `<!f`. Then again, I'd be even more horrified if the above statement is not true anyways.
- eyelidlessness 5y agoHad to try it! Here is some horror for your day: https://codepen.io/eyelidlessness/pen/abVrjQq https://codepen.io/eyelidlessness/pen/abVrjQq
- chayleaf 5y agothis is <-!, not <!-
- HAL9000Ti 5y agoIt's 0<!-f in the code, just not in the html text
- eyelidlessness 5y agoThanks both, fixed! That’s what I get for coding on my phone
- LordDragonfang 5y agoFor anyone confused, this is actually (semi) sane behavior by javascript standards, because it relies on `-"f"` evaluating to NaN. Of course, because javascript, there are other string values of `f` for which the two statements are equal as well. (e.g for empty string both statements are true because `-"" === -0`, and for "1" both values are false) https://codepen.io/LordDragonfang/pen/KKyLjLg https://codepen.io/LordDragonfang/pen/KKyLjLg
- eyelidlessness 5y agoWhile we’re at it, here’s some more madness… this time with booleans and numbers! https://codepen.io/eyelidlessness/pen/yLPdLey https://codepen.io/eyelidlessness/pen/yLPdLey
- srcreigh 5y agoThis one really gets to me. f = 0 (type: object, constructor: Number) 0<!f = false 0<!-f = true
- eyelidlessness 5y agoI’ve tried three times to write why I think this is, and each time I get lost in my reasoning. Alas, I’ve been on mobile for this whole thread and I don’t have any more brain cells to try to code like this tonight lol
- Leszek 5y agoIt's because `f = new Number(0)` is a boxed number (therefore it's an object), and `!f` calls ToBoolean on this object which unconditionally returns true (https://tc39.es/ecma262/#table-toboolean-conversions https://tc39.es/ecma262/#table-toboolean-conversions). `!-f` first applies unary minus, which first performs a ToNumber on the f object (which returns unboxed 0), that's negated to -0, and then ToBoolean of -0 is false.
- 5y ago
- eMSF 5y agoThe two are certainly not always equivalent (for example if f is an object). `<!-f' might be always equivalent to `<!+f', though.
- wjmao88 5y ago<! is less than or not equal right? which is a strict subset of !=, since anything < by definition is !=
- dragonwriter 5y ago> <! is less than or not equal right? No, it is less-than-not, not less-than-or-not-equal-to. That is <!x is the same as < (!x); if x is true-ish, it is “< false” and if x is false-ish it is “< true”.
- bilalq 5y agoIs V8 unable to remove this because of old, poorly-written websites? Can it maybe shut off if it detects strict mode or something? Seems wild to find this behavior in Node and evergreen browsers.
- Leszek 5y agoHaving it in there optionally would be even more awkward, and getting rid of it entirely isn't possible without changing the JavaScript spec /shrug
- int_19h 5y agoIt's part of the language spec.
- bilalq 5y agoRight. My question was to ask what it would take to remove it. Backwards compatibility is a concern, but could strict mode or some other flag be used to mark it as disabled?
- gregsadetsky 5y agoSource: https://github.com/v8/v8/blob/main/src/parsing/scanner-inl.h#L382 https://github.com/v8/v8/blob/main/src/parsing/scanner-inl.h... and https://github.com/v8/v8/blob/main/src/parsing/scanner.cc#L320 https://github.com/v8/v8/blob/main/src/parsing/scanner.cc#L3... And also this nice article: https://v8.dev/blog/scanner https://v8.dev/blog/scanner "The scanner chooses a specific scanner method or token based on a maximum lookahead of 4 characters, the longest ambiguous sequence of characters in JavaScript"