Humans are fallible. That is an immutable truth.
There’s no great wisdom in relying on human discipline alone to produce reliable software.
Else we'd all be using assembly.
There's absolutely no pride or glory in doing things nicely and securely that the computer could have automated in the first place.
Anything the language allows that it could refuse while allowing devs to express the same features, and that results in bugs is a mistake in the language (e.g. the sorry state of strings in C).
I've seen an attitude that people think they can inoculate themselves from inept programming by using obtuse frameworks as if martin-fowler-speak acts as a drill sergeant making disciplined coders out of the herd.
But after 20 years of bouncing around startups I've never seen the intended results actually happen a single time. Not even close. Not once. Never.
Instead it leads to larger, less maintainable, more convoluted messes that have to be trashed quicker. Giant ceremonial cargo cult style monstrosities with huge circuitous logic - 4, 5, maybe 6 layers, a router calling a controller, calling a service, calling a provider, calling an event model, which runs a single if statement ... as if that's how we protect ourselves against incompetence.
These approaches just lead to wasteful projects where they end up rewriting the whole thing in whatever the framework/language de jour is instead of writing easily maintainable, quickly understandable code that's designed to work for the next 10 years. I've talked to many programmers who are embarrassed by the language they are using ... wtf is that?! They've turned programming into fast fashion.
Then people like to ask what someone's favorite language is, usually when they first meet them, as a social cue, as if we are a bunch of highschool kids following pop music. I mean what on earth... we're supposed to building the future here, not running around like a bunch of spastic fanboys from platform to platform, just to mess everything up all over again in bold new ways using slightly different syntax.
The best thing to do is give people the least abstract thing with the fewest conformity requirements ... essentially make it open ended and then the messes are easier to spot and easier to fix. You won't get 4 folders with 26 files handling simple tasks like uploading images to an S3 bucket (saw this huge mess just last week and guess what?! It's broken. I know, surprising right?)
Anyway, new shiny fancy tools with GoF buzzwords won't ever fix incompetence, it'll only make it worse.
Which is neither here nor there.
For one, it ignores the pragmatic issue, that very competent people (the very people that built the foundations we all work on even) will still make lots of mistakes, even trivial ones, but with severe consequences (e.g. buffer overflows) when the languages don't prevent them.
If only it was just "incompetent people" that made mistakes...
>But after 20 years of bouncing around startups I've never seen the intended results actually happen a single time. Not even close. Not once. Never.
You weren't looking hard enough. Every day millions of programmers don't make "buffer overflow" errors for example, that otherwise they'd have made, because they work in languages that don't allow them.
And they'd have made those mistakes regardless of their programming chops. The best programmers, people that run circles around you and me, still make those mistakes.
It's about giving code sunlight so that action at a distance and other kinds of magic don't hide errors making them harder to find, get in your way of fixing them, making reproducibility a mess and confirmation simply guesswork.
Its the restrictive design trend of crippling languages which needlessly prevents the sunlight effect from happening along with "information hiding principle" gone completely amuck with the information successfully hidden in dozens of innocently named files with listeners, observers, watchers, triggers and who knows what else being mysteriously called based on reflective programming so not even grep will help you.
Static code analysis and seamless navigation is totally a thing of the past.
Instead, the errors will have the stack of the error handler and that's it. The debugger is useless because stepping through the code is 98% scaffolding.
All these fancy tools bludgeoning any introspection or diagnostic system so the only remaining workable debug system is printing debug variables and rerunning the code like I'm programming on a TI-81 (only that had debug and release run modes...features I can usually only dream of these days) Progress! Welcome to 2019!
It's crazy. This isn't how maintainable code is written
The way I think about it is if you think through the entire software stack and all the instructions that get executed across all the machines and their operating systems and programs running underneath before things even get to your code and then all of the standard library and framework code plus your code. For just a simple loading a web page that is a trillion piece jigsaw puzzle and every single piece has to line up or the whole thing just doesn't work.
We do the humbling and the remarkable every day and trillion piece jigsaw puzzles are no joke. It's the exception that you get it right. Given all the pieces required that's a lot of sources of potential entropy and the more it increases the more the system destabilizes and/or becomes unworkable. Things like languages, libraries, frameworks etc make certain decisions on your behalf with the goal to contain some of that entropy within their given abstraction.
I think I'm justified in calling myself competent. Nevertheless, with the wrong tools, the things I build are definitely worse than the things I can build with proper tools.
I mean it's just a huge waste of time. These modern stacks (mostly js) are crap code all the way down.
It's made me want to return to Perl because honestly, it has everything and is somehow mostly idiot free. I probably should...
It's 4am, I should sleep.
The moment you convey that sort of attitude, two things happen. The person you called a flunkie will not learn a goddamned thing from you. And, if they happen to be right, you won't learn a damned thing either. Great choices.
However, you can pursue a culture of excellence without being rude and toxic. You can be kind and humble without coddling.
Edit - I should have added that if teenagers with computers have a good attitude, feel engaged and feel cared about, they can be extremely productive members of a team. And they have a tendency to grow into really amazing engineers (and fine people).
You can see right here on HN anytime a post comes up about using a cloud provider someone advocating putting a layer of abstraction over the provider’s SDK to prevent “lock-in”. As if the CTO is going to one day move their entire infrastructure because a developer promises them they’ve abstracted their code perfectly.
So instead of just being able to read the docs of the SDK, you have a custom QueueManagerFactory that gives you an AWSQueueManager that wraps the Boto3 AWS SDK just so one day if the company decides to move to GCP, someone can write a GCPQueueManager.
See also, developers who think they can effortlessly move from their company’s six figure Oracle installation to Postgres because they used the repository pattern.
This is despite the fact that if you do it it'll take 40 minutes manually versus 10 minutes if the Rube Goldberg abstraction machine works as planned (it won't).
Since there's only about a 5% chance (max) that going from say S3 to Azure will ever happen, the extra cathedral of abstraction saves an actuarial 1.5min of dev time.
All that only for 2-4 days of development to make it and the added runtime at every request for the convenience. Genius!
I'm not going to write raw HTTP requests to S3 in every place in my code that I need to read/write objects from there. What I'd rather have is a simple abstraction with methods like get(id) -> obj and put(obj) -> id.
Yeah I have been through that before where the architect of the company wrote his own bespoke ORM, logging framework, etc. and he was the only one who knew how it worked.
It's art, fashion and politics.
It's not binary. It's probabilities. Some environments make it harder to mess up, others make it easier. This is real.
Brands generally mean nothing to me, new consumer technology I'm generally not interested in, and I have no issues say, taking the bus and getting reading done instead of rolling around in say a Tesla (despite the fact that buying one is well within my financial reach). I honestly don't care in the slightest.
So yes, it's probably a larger personality disposition which manifests itself in this particular way moreso than it is a morsel of objective rational reality.
The people I lambast are the same ones with things like smart speakers and wifi connected refrigerators (I use an old minifridge and I prefer it). It's just a lifestyle; not some objectively poor use of money and time resources.
That's a nice perspective and it helps explain a lot, thanks.
It appears that we think about different terms when visualizing what "incompetent" means.
We create languages to tackle different sets of problems, and we want to minimize human error - that part, I believe, we can agree on.
However, if you perform "SELECT * FROM mytable" (table grows indefinitely) and then sort / limit in the language and not database - you're incompetent, you simply lack knowledge and you didn't even think abstractly what can happen by doing so. There's no language out there that can teach you "right tool for the job" or "keep it simple" or "should I do it, maybe there's another way, did someone else have this problem?", no matter what wizard creates it.
We will never weed out incompetent people by creating languages and a language shouldn't cater to a moron.
There is a reason most web sites don’t use C.
Invisible characters are a problem in every language, configuration file, file period, trying to suggest that its specific to php is just silly.
PHP does something different. It outputs it early and when you try to send a header it tells you that's too late. That error is in no way helpful to you at that point unless you already know about this issue, and it won't even help you figure out which file was affected. That part is specific to PHP.
I'm not familiar with Lua pages, but all I can find uses a http / fastcgi server with explicit routing. ASP classic has its own terrible ideas and it's close to death now - 2025 is the last year MS committed to support it, so I don't really think of it as an interesting language anymore.
In a complex product (as in, most professional settings or large services/web sites) the PHP I've seen is grossly complex, and not intuitive—especially WordPress deployments.
Dev teams have to perform all kinds of gymnastics with the PHP code to get it to do what they want, and it's just a flat out nightmare that I've made sure my boss and colleagues know that I have no desire to work with it.
It always ends up a house of cards and full of vulnerabilities so that something is regularly getting exposed that allows at least editorial access. Security issues that should otherwise be no problem.
God knows how many other vulnerabilities exist. Every single server I've ever had has had bots and crawlers polling for common PHP files in an effort to exploit them, should they exist.
I just don't like having even the chance that my back-end source could, for want of a single character, spill out to a web page upon request.
And then there's performance...
Anyway for simple things, sure. For things that don't require much security, sure. For anything else... it's not for me.
I've done enough WP to certainly agree with you. However, I don't think it's fair to judge PHP by how WP has abused it.
WP problem is its desire to sacrifice code quality and best practices for market share. That is, many things don't get refactored (into something OOP based) because there might be backwards compatibility issues. Again, this isn't PHP's fault.
That said, I'll never go out of my way to use it for much else—let alone serving and routing something public-facing ever again.
I like that it's forward-thinking, but it moves so fast that it has negative impact on user (i.e., dev) experience.
Yes, but the holes and gotchas are worse when they are baked into the language. The thing that Golang gets right, is that the developers are willing to eschew features to avoid gotchas. It's like other languages are sports cars with sexy lines and fancy features that everyone wants, but have to spend more time "in the shop." (An analogy for in the debugger.) Golang is more like a base model Toyota Corolla with a manual transmission.
Not sure what PHP is like. Maybe some sort of modder car. Like Perl and Ruby, PHP grew by readily adding features in response to demand. In that way, it's the opposite of Golang.
PHP is much less complex than most.
That depends on what level you're looking at. PHP is one of those languages that has a lot of complexity baked into it in the form of language design warts. In order to make it a nimble language, you have to ignore/eschew parts of it, and stick to some "good parts."
I'll be flask-ing
And as a result also easier to achieve proficiency in.
Just because it works, doesn't mean it's good or secure. And while it's very easy to see if something works or not, it's very hard to see if something is secure.
I’d rather there be some learning curve so people understand what they’re doing (or not doing).