The older ones among us remember when XML took over the world and everyone was supposed to use strict XHTML. It turned out that the strength of the HTML ecosystem was its fault tolerance. HTML4 was the "sloppy" answer to XHTML. It brought HTML back from a data language to a markup language. Every Markdown parser is similarly fault-tolerant as HTML parsers.
However, CSS and JS are not error-tolerant. A syntax error in a CSS rule causes it to be ignored. An unhandled JavaScript exception is a hard stop. This way, web does not run on tolerance.
I think you mean HTML5, which exhaustively specified how to do parsing in a fault-tolerant, normalizing way. HTML 4 (and 4.01) predated XHTML 1.0, and HTML 4.01 attempted to take things in a stricter direction, introducing a "Strict" DTD that did things like drop the <font> tag, in pursuit of separating structure and presentation.
Funny enough my impression of JS (the kind you'd write in 2007 more than the type you see now, mind you) is that it's remarkably tolerant; many idioms and operations which would cause, in other languages, runtime errors or compile errors, would just get steamrolled over in JS because of just how much built-in flexibility the uber-weak type system (plus liberal use of the prototype pattern in the stdlib) allows for.
- Wanna subtract a string from a number? That's not a type error, that's a `NaN` -- which is just a perfectly-valid IEEE 754 float, after all, and we all float down here.
- Hell -- arithmetic between arbitrary data types? Chances are you get `[object Object]` (either as a string literal or an *actual* object), which you can still operate on.
- Accessing an object field but you typoed the field name? No worries, that's just `undefined`, and you can always operate on `undefined` values.
Frankly, while I haven't had a frontend focus in about 15 years, I struggle to think of any situation where calling a stdlib function or standard language feature would result in an actual exception rather than just an off behaviour that'll accumulate over time the more of them you stack on eachother. I guess calling an undefined variable is a ReferenceError, but beyond that...
(This comment shouldn't be taken as an endorsement of this school of language design)
It is also (nearly) impossible to completely crash a web page. There isn't a main loop that can panic out. No matter where an exception gets thrown, the overall application keeps going and responding to events.
Can't access a network resource? API returns an unexpected error? Library crashes? Browser extension breaks something? Doesn't matter. The user can still view and scroll the page, and the rest of it will probably keep working, too.
Application error: a client-side exception has occurred (see the browser console for more information).
The amount of articles on HN that render perfectly, then vanish a second later and are replaced by this error message is insane. Yes, I'm using an old unmaintained Android HN reader with a questionable webview. No, that's not an excuse to delete a perfectly rendered from right in front of my eyes.
Sure. But it's not the browser that did that. You see the dialog because the app HANDLED the error condition, and application code displayed an dialog. Had the error not been handled, the browser's behavior is to log a message to the browser console (which you, as a user, never see), and carry on, pretending that the error never happened. So the page would have continued on in some non-functional, or half-functional state.
> However, CSS and JS are not error-tolerant. A syntax error in a CSS rule causes it to be ignored.
This is good though as it provides a means for progressive enhancement using new features only when they are available and falling back on previous rules if they are not. It's very different from the syntax error -> RIP page nonsense of XHTML.
In the CSS half, in the JS half it's really no different. Of course that's fine because "best effort logic" doesn't provide nearly as much value as "best effort layout".
> It turned out that the strength of the HTML ecosystem was its fault tolerance.
I don't think this was a "strength" of html so much as a necessity to not break the internet. I certainly preferred the formal nature of xhtml to html 5. But, we're stuck with needing to render obviously formally-broken documents.
The benefit accrues to developers, who get more consistent behavior across browsers. In the bad old days, errors that one browser might silently recover from would trigger unspecified recover behavior on other browsers that wasn't consistent.
Nonsense. Open the console on l any mediocre webpage and you’ll see a stream of JavaScript errors. But it’s still working. One script crashes? Doesn’t matter to any other script. Unhandled exception? Rest of the app is still working fine. Hell, that button may work if you just click it again.
And CSS syntax error causing only that single line of code to be ignored while every other line of code works fine is the very definition of fault tolerance.
All that is very good. But as a back end guy dabbling in front end, it would be more welcoming if JS was a little intuitive. I'm very thankful for LLMs now helping with that a bit, but honestly even they seem to fail at JS more so than other languages, at least in my experience so far.
Much of the challenge in JS today is due to unnecessary packages, build systems, and workarounds found throughout blogs and forums which were reasonable 5-10 years ago but aren't really needed today. Unfortunately, LLMs tend to output old-fashioned JS.
With (almost) everyone using an up-to-date standards-compliant browser, you can sidestep most of the complexity and weirdness by just using the standard library and ES Modules (instead of frameworks, libraries, build systems etc.) and an IDE with good intellisense + inline documentation lookup.
MDN documentation is good and up to date overall, but I'm not sure there is a good overview/entry point resource that is up to date as of today... maybe I'll have to write it!
I don't know if my experience is any guide but for me, coming from C++, I hated JS (~2008 is when my job required it). I kept trying to use it as C++. Over time I learned to love it. I stopped trying to make it C++ (or Java/C#, etc...) and actually embraced it.
Now the tables have turned (to some degree). I can write programs in JS in 1-3 days that take weeks or months in C++/C#/Java
Some of this comes from the browser environment. I get portable 2d/3d/gpu graphics, portable audio, image loading, video playback, and complex text rendering and layout, portably and for free. Back in C++/C# land, every new project is a chore of setup and fighting with linkers and build options etc. I post some code in a github repo with github pages on, or in some JS playground like codepen, and instantly share it with all friends regardless of platform.
Another comes from the language itself. I can often generically wrap existing APIs in a few lines of codes, things that used to take days and/or large program refactors to do in C/C++.
And, the tools are pretty good, Chrome DevTools are as good or better than my experience in C/C++. Right now, when I try to debug in C++ in XCode, std::string shows nothing and containers are inscrutable. I'm sure that's fixable. The point is, I shouldn't have to fix basic stuff.
Now of course I'm using TypeScript for some projects and the types help but I'm often glad for the escape hatch for more generic code. It takes me 15 mins to write some generic system in JS and then 2-4hrs to figure out how to get TypeScript happy to type it. As an example, a function that creates a new TypedArray of the same type as some src array. Easy to write in JS. Harder to type in TS. That's effectively part of the same issues I have in C++, the part that stalls progress, that I don't have the escape hatch for generic solutions.
PS: Yes, it's not that hard to type a generic TypedArray function in TS. But it's certainly a learning curve, or was before LLMs, and I've had to type much more complex functions that required no typing in JS
However, CSS and JS are not error-tolerant. A syntax error in a CSS rule causes it to be ignored. An unhandled JavaScript exception is a hard stop. This way, web does not run on tolerance.