Good article, and I agree with the author's enthusiasm.
However his points that "cheap parts are a great enabler" and "shipping costs are high to Trinidad and Tobago", while true, don't actually counter the OP's points that "feature determination needs to be universal" and "the instruction set is poorly designed".
Others have said application authors will code to the specific platform, but that's not true of library authors -- they need portability.
Why can the RISC-V team not get basic stuff like feature determination right? No matter how stupid the rest of the instruction set is, I'm with OP that the responsible individuals should retire from the committee.
A typical place this distinction is useful is that it determines whether the test-suite runs to completion with multiple tests, or panics/terminates hard on the first failure.
Some of it is Conway's Law, much though seems purely "cargo cult engineering" or "FAANG cosplay".
Less-competent devs and CTOs hear that Amazon & Google use it, then decide their 12-person team needs to rewrite their product as 5 separate services. I have encountered companies with 50 services where they needed 5, spending 60% of their dev velocity on overhead.
If you're contemplating microservices & haven't already nailed your business transaction boundaries, reliability mechanisms, idempotence, deployment management/ versioning, observability, testability and the operational discipline to run distributed systems you should just stop -- you have no freaking clue and you're going the wrong way.
Or not. For simple to moderate requirements, plain HTML with a small templating helper is genuinely simpler than React.
React’s complexity isn’t just components — it’s effects, state‑management conventions, data‑loading patterns, and the surrounding build ecosystem. If your UI doesn’t need those abstractions, adopting them early is pure overhead.
For these kinds of projects, React usually carries a much larger total cost than vanilla HTML + JS.
The “vanilla becomes a bespoke framework” claim assumes the UI will inevitably grow until it needs framework‑level abstractions. Most UIs don’t. React front‑loads complexity even when the UI is small, while vanilla only adds what the actual requirements demand.
A few helpers aren’t “reinventing React” — they’re choosing a simpler design avoiding numerous unnecessary abstractions, and with lower costs & complexity for the moderate apps they're building. It's a very valid architectural choice.
You've assigned `grid-area: main` to the content but the parent grid doesn’t define "main" in its grid-template-areas; the browser creates an implicit grid row/column to satisfy the placement, and this ends up being below the defined areas. Thus requiring 1 page blank space to scroll down.
You can investigate the `<div class="main-content">` in Dev Tools by toggling the 'grid-area' CSS attribute off; that fixes the display.
What an incompetence & embarrassment. This seems like a failure of product management, management & executives rather than actual software craftspeople.
Those responsible -- all of the people -- should be promoted to digging ditches.
> This seems like a failure of product management, management & executives rather than actual software craftspeople.
I’d say it’s all of them. A developer that doesn’t stop to consider that it is just absurd to validate an input box while it is still in focus is a developer that is very clearly lacking. But then again those higher up in the command chain also let it slide and actually be released.
So yeah, lots of people to blame here. Including the devs.
Does the Zig language not have useful exceptions/stacktraces that can be propagated out?
At a high level, all non-trivial programming is composition. And (see principle of encapsulation) the vast majority of errors shouldn't be recovered and just need to be propagated out.
Then, to be useful, errors need enough information to be diagnosed or investigated. It seems like this should have been a straight-forward requirement in the language design.
Zig has error unions on return types which are basically a special cased (rust enum aka sum type) of the return type with a special cased (c enum aka enumerated type), and stacktraces are only available in certain build modes.
A "diagnostics" pattern has emerged in the community to optionally request extra information about a failure. You can pass a pointer to the diagnostic (it can be on the stack) and get the extra info back. It's just a more explicit version of what would otherwise happen in a language with error payloads.
> stacktraces are only available in certain build modes.
Minor correction: stack traces are available on all build modes, but different build modes have different defaults. See: std.Options.allow_stack_tracing
Note that this "diagnostics" pattern is only meant for handling a error locally with potential extra information, or showing a more useful error to a end user of the software. For software bugs, crashes, or developer facing errors, you often don't have to do anything as zig has pretty good error traces by default.
You can enable error traces for release-fast builds as well, without enabling full debug info. Though the quality of call stack of course vary depending on optimization level.
Exception handling would be better than what we're seeing here.
The problem is that any non-trivial software is composition, and encapsulation means most errors aren't recoverable.
We just need easy ways to propagate exceptions out to the appropriate reliability boundary, ie. the transaction/ request/ config loading, and fail it sensibly, with an easily diagnosable message and without crashing the whole process.
C# or unchecked Java exceptions are actually fairly close to ideal for this.
The correct paradigm is "prefer throw to catch" -- requiring devs to check every ret-val just created thousands of opportunities for mistakes to be made.
By contrast, a reliable C# or Java version might have just 3 catch clauses and handle errors arising below sensibly without any developer effort.
Interesting to see Rust error handling flunk out in practice.
It may be that forcing handling at every call tends to makes code verbose, and devs insensitized to bad practice. And the diagnostic Rust provided seems pretty garbage.
There is bad practice here too -- config failure manifesting as request failure, lack of failing to safe, unsafe rollout, lack of observability.
Back to language design & error handling. My informed view is that robustness is best when only major reliability boundaries need to be coded.
This the "throw, don't catch" principle with the addition of catches on key reliability boundaries -- typically high-level interactions where you can meaningfully answer a failure.
For example, this system could have a total of three catch clauses "Error Loading Config" which fails to safe, "Error Handling Request" which answers 5xx, and "Socket Error" which closes the HTTP connection.
> It may be that forcing handling at every call tends to makes code verbose
Rust has a lot of helpers to make it less verbose, even that error they demonstrate could've been written in some form `...code()?` with `?` helper that would have propagated the error forwards.
However I do acknowledge that writing Error types is boring sometimes so people don't bother to change their error types and just unwrap. But even my dinghy little apps for my personal use I do simple serach `unwrap` and make sure I have as few as possible.
I don't understand how your takeaway is that this is a language flaw other than to assume that you have some underlying disdain for Rust. That's fine, but state it clearly please.
The end result would've been the exact same if they "handled" the error: a bunch of 500s. The language being used doesn't matter if an invariant in your system is broken.
Fable 5.1 -- to my early impressions -- seems to have gone backwards again.
Opus 4.8 was terrible for babbling self-invented jargon. (But still better than other options at the time for coding and logic.)
reply