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.
Humans are fallible. That is an immutable truth.
There’s no great wisdom in relying on human discipline alone to produce reliable software.