Developers are fallible humans and almost every single developer tends to underestimate the complexity and difficulty of what they're dealing with. Even those developers who are naturally good at coding are nowhere near where they need to be to produce merely correct code. Not outstanding, readable code, just correct code.
Modern software has become an inseparable amalgamation of people and code because the code on its own is just not good enough. DAOs which can operate on their own with minimal to no human intervention are still a pipe dream.
No, they went out of business to some other company that wrote imperfect software with a lot more features a lot faster!
Especially in the '90s I remember hearing the "Why does everyone use X, it sucks and it crashes", and yet whatever X was tended to have a broad range of features clients needed.
It made me wonder what a “no compromise craftsmanship” computer or software would look like. For one, it would never truly get done, there’s always more to do, but then again I guess that’s the same with the 25 year calligraphy brush.
Dwarf Fortress fulfills each point of your criteria, and some more that I could add. It's an epic achievement.
I don't play it. I've never invested the brain cycles it would take to learn the interface, and I know that if I did I'd fall into a deep, deep hole that'd compromise every other priority in my life.
I don’t play it either, I tried it once or twice and it was just too much for me. I might try their new graphical steam version that they released last year sometime, it looks a little more accessible.
I find it fascinating because my use of software seems bug free in last 5-10 years. It is hard for me to run nowadays into a frustrating bug.
When I was in high school there were just loads of bugs and everything seemed broken it was 2005ish and before. Windows was crashing now and again, had to reinstall frequently, software was crashing taking my work with it so I still have compulsive ctrl-s tick.
- Firefox randomly freezes up on Android (Google Pixel 6a), and then sometimes this crashes my phone and causes it to spontaneously restart. This usually happens at least once a day, often more, despite being very widely reported for a very long time.
- Assorted Adobe software develops strange behavior after it has been open for a while (selected items stop showing as selected, some tool or editing technique spontaneously stops working, exported images are borked, pressing ctrl+S reports that it has saved the file but it actually has not, etc). I have probably seen 50+ unique failure states over the last couple of years. I am affected at least a couple times a week, and I have learned to restart my software several times a day as a preventative measure.
- On desktop (Windows), some website will fail to load something or it may display bizarre behavior (erratic scrolling long after the page has loaded, back button stops working, links stop working, video playback stops working, etc.). Usually reloading the webpage fixes it, but sometimes the tab itself has broken or the browser has to be restarted. Other times, it's a consistent bug in the website and there is nothing to do but wait a couple days for them to fix it. I usually see website/browser issues like these about once a week or two.
It's better than the 90s, but it's still pretty bad and could be way better (as proven by all the software/systems/sites out there that don't have so many bugs).
It doesn't have to have an explicit bug in order to be shit.
There's too many instances where something is doable, but only painfully so. copy/paste over the last 10-15 years is a perfect example of something that isn't bugged but is complete shit in most software nowadays.
search is another one, how often have you been on a website where ctrl+f doesn't work right because subsequent data only loads after you scroll below the fold? no bugs, but still shit software.
I actually tried writing a section of my blog called "Everything is Broken" to cover some of the ways software breaks in (as well as some issues in general): https://blog.kronis.dev/everything%20is%20broken
Unfortunately, there are so many bugs out there, that I only write about the things that are annoying enough to push my hand. Some of the last things that happened to me:
* Ubuntu LTS updates broke my GPU drivers, preventing the server from starting up (among other things)
* Debian updates made some unnecessary piece of software start listening on port 25, thus breaking my mailserver in Docker
* OpenProject packaged PostgreSQL inside of a single container, except that didn't bother setting up automatic data migration for new major version
* Vector maps are somehow way more laggy than raster tile based maps, horrible user experience on mobile for me (video included)
* a trailing comma in Visual Studio Code configuration file made fonts end up being non-monospaced
* Kdenlive (probably due to ffmpeg) failed to correctly apply text titles on top of a video at the correct times
* containers break due to different file system permission models on Window and Linux, bind mounted files have incorrect line endings
* Nginx crashes the entire web server if something like 1 out of 20 reverse proxied domains doesn't have a successful DNS lookup on startup
* Grav (blogging software) can have changes be made to the install without admin authorization, my blog got vandalized
* Oracle database randomly dropped connections, some relation to a generated column
I've also had issues with GRUB, disk management in Linux, Nextcloud, Libre Office, OpenCV, Docker Swarm and pretty much every class of software (desktop, web, CLI tools, GUI stuff, OS components) out there - sometimes in pretty exciting ways of them breaking!I also have a folder on my computer where I collect screenshots of software breaking out in the wild, currently it has 143 images, though perhaps that's a bit too much for blog posts. Currently the last 10 there are:
* Mozilla Observatory failing to analyze my site due to their own CSP being broken (script-src)
* PHP install failing because the ondrej/ubuntu PPA failing to work like it should
* my bank login page having an untranslated text string for one of the options: #xml-dtd.LOGIN-TEXTS.LOGINEPARAKSTS
* my mobile service provider telling me that I've used 212166% of my mobile data
* me being unable to modify a Visual Studio Build Tools install locally because they want to update their installer but I'm offline
* Windows 11 Explorer breaking the file path bar and showing me two overlapping text strings for some reason
* Oracle not giving me my OCA cert because my name contains non-ASCII symbols
* the War Thunder game telling me that I have 2147483647 crew available for my tank
* OpenProject functionality to move multiple issues failing... despite them having a dialog exactly for that
* installing a Ruby Gem following official SQLite instructions results in UDS:Trojan-Downloader.Win64.Alien.eg/ef being detected
Aside from that, perhaps my favorite bug is this: https://i.imgur.com/97wu8j5.jpeg- not really a bug, just system was not build to support scenario - not really a bug, user does not understand system thinks it should work differently - not really a bug, combination of 2 or more software things that have no way of knowing about each other - not really a bug, because it does not affect me in any meaningful way
There are some I can agree are bugs of course. Though I see I am getting older and much more humble and lenient.
For humble it is that if I expect some software to work some way and it does not, I step back and really go back to understanding documentation and what it all means. I don't call out things "fail to work like it should" (which of course might be my issue and parent poster might be right calling it out).
Then for lenient, I just don't care about labels, text misalignment etc. The same with expecting non-ASCII symbols being supported, yeah we have UTF for quite some time, but it is also not something trivial to switch to and company most likely has loads of other work to be done.
In the end world is not about me and there are tons of users who have other issues and my edge cases are not affecting enough people. World is much bigger so to say. If it does not affect me in any meaningful way I just move on.
For example, if software works in a configuration that was setup correctly (according to their own instructions) in version #1 and after update the version #2 makes the setup no longer work, is that a bug? I'd probably say it is, unless the patch notes clearly instruct that something needs to be done, though even that can be debatable. What about the case where you don't even consent to install some package that will take up a port on your OS and break something else, but it silently gets pulled in through some update? There's probably nuance to it all.
At the end of the day, as a user, I might subjectively not even care about the internal workings behind some abstraction and the many reasons behind it, but rather about how it should work in a reasonable configuration - if a web server refuses to start if it cannot resolve a domain that it's supposed to reverse proxy when starting up, even though the other 19 out of 20 could be proxied, is that a bug? Probably not, but it sure seems pretty darn broken, since those 19 could be served and the faulty domain simply checked later.
Of course, the software itself doesn't care about the user either, so at the end of the day it is the user who needs to learn patience and to trudge through the docs, posts online and other sources to hopefully resolve the issues, even if it's a bunch of weird workarounds or concessions, no matter how frustrating they might be. But hey, there's nothing wrong with documenting said frustrations or issues.
I am glad that you've embraced a more neutral mindset, though!
Putting on the proverbial blinders and declaring software "better now" is not really something I'd consider neutral, to be honest. Sounds like expectations dropping over time, more than anything. Note how there are plenty of real examples of outright bugs that are left unaddressed here and no acknowledgement that yes, the world of software is full of them.
I don't particularly care whether someone has a rosy outlook in general, but it's pretty odd to declare that software is somehow so good when it's at the very least as bad as it was in the early noughts.
It's understandable that people don't like overly pessimistic people dooming and glooming too much but I find the inverse equally if not more annoying. If you factor in how much slower most software experiences are vs. what our hardware should achieve plus all of the bugs that are at least as plentiful if not more our general software output is much, much worse than it ever was. We're not even producing it much faster because of galactic scale overcomplication in software stacks as well.
I would encourage you to write down bugs when you see/experience them but in all honesty I don't know that it will give you much; it will probably only completely destroy your positive outlook on things that you seem to have retained.
- On YouTube sometimes the interactive elements of a video (quality settings, etc.) will also scroll my page down about 15% when I interact with them. If I click on the settings wheel to change the speed of the video that's 3 clicks and I'll end up ~50% scrolled down from the video I'm watching.
- YouTube randomly resets my settings for inline playback when I disable it. With inline playback "Add to watch later" is not available as a thumbnail hover option.
- When I was running Windows it would randomly set my bluetooth headset volume to close to zero out of nowhere without any changes made on my end, but only on a reconnect, so I would always have to check every time I connected whether it had done it.
- Sometimes when my bluetooth headset connects on Linux I'll just plain have no sound at all despite it saying it's connected. The workaround is to just reconnect.
- During a routine package upgrade for some reason something installed `xdg-desktop-portal-gnome` and this made every application that uses GTK (I think) start about 10 seconds slower. Uninstalling this package solved it.
- Thunderbird will leave an empty e-mail subject line sometimes when I delete an e-mail I've received, but the body it shows when I click it is another e-mail I deleted.
- World of Warcraft will randomly lose connection despite there being zero connection issues and rejoining will immediately work. This happened maybe 3-4 times per week in the 3 week period I played recently.
- Discord sometimes just removes my key binding for toggling push-to-talk.
- Elixir (via `mix`) refuses to compile dependencies sometimes and solutions range from having to remove folders, update deps and all manner of things. There's usually no real rhyme or reason to it and we all just nuke a folder or two and move on.
- Same as above but with `node_modules`.
- We had a package from `npm` that would sporadically not type check with our usage and we could never figure out what it was caused by. Every 20th or so build `tsc` would report a type error where none had existed before. This was with pinned versions.
- When I used VSCode I would regularly end up in a situation where VSCode suddenly started saving files super slowly and took forever to auto-format code. This happened with at least 3 different languages so it was not language or extension-specific. I've also seen it happen live to at least 3 other people.
- Plex will die when playing video files of a certain quality on my TV despite playing them fine for ~15-20 minutes.
For any system that is reasonably complex; that solves a real world issue, there's simply no way to handle all the edge cases.
One thing that I've found myself doing in recent years is to simply let the program blow up and have the end user experience a 500 error. I know this isn't ideal for so many orgs but I've come to the conclusion that the worst thing you can have happen is a feature that breaks but returns a "200".
Acceptable for webapps. I can't really think of anywhere else that it becomes acceptable to simply say "We had an oopsie. Try again later".
Mostly what you want to do is give the user an actionable error message - i.e. "This is what you can do to fix this error".
"cd /somedir" gives errors of the form "permission denied" (i.e. change your perms level, or ask the owner of the dir to change its permissions), "not found" (i.e. that dir does not exist, so create it if you need it), "i/o error" (i.e. your disk may be bad, run fsck), "Not a directory" (i.e. specify a directory, not a file), etc ...
With most programs written in HLL these days, all I get is something along the lines of "Operation could not be completed", or, worse an exception handler that has absolutely no clue what is needed to fix the error (a real one I got last week: "expected integer, got string". I have no idea where in the 3k lines of input that field actually is, or what it is called).
The only good error messages I see are written in programs that don't have exception handlers, so the error is printed out where and when it happens, and the programmer who wrote the code that generated the error is also forced to handle it, and so has all the context to generate a reasonable error message.
Within certain domains like healh-care (my area these days), space travel, military, edge case management play a significant role in the valuation of where to place your effort (although it doesn't exclude the ability to fail fast and hard during development cycles). In other domains exposing users for these hard failures is considered perfectly fine. It depends...
It's just one other aspect - when thinking beyond just the code - that makes the decisions and consideration I have to make every day "hard".
Reminds me of Petet Gabriel's Worse Is Better[0], one of the insights of which is that it's often better to fail for edge cases than try to handle every single one.
The question is what constitutes an error and should web semantics and application semantics align?
should I return a 404 on a missing record, and if I do, how can I differentiate between that and a routing error?
My point is that you're confidently stating something where both sides are neither right nor wrong, they simply value different things.
This message brought to you by a day of commits dealing with edge cases that only manifest in the cloud environment which uses a "strategic" database technology that is impossible to run locally.
And it deploys from one of our old crappy Jenkins pipelines that decided 30 minutes ago to start having a failing volume.
Should have just used GitHub Actions + Postgres.
Everyone has a test environment, some people also have a seperate production environment :D
Database/datasize issues typically are the worst here. Dev/UAT environments are typically considered a cost center and you'll commonly see them with some small amount of ram and compute resources. Which is fine when you're testing 'small data'. But if you have enterprise style clients that have hundreds of gigs/terabytes of data, your dev environment behavior is generally going to be very different.
Ran into a case where an enterprise client ran massive db performance problems. We found an unindexed table scan that was killing performance. When doing a post mortem on it, it turns out that 95% of our customers only had around 5 entries in the table. No reason to add an index to that. But this customer had found a neat and interesting workflow that had added thousands of entries to that table.
Did you consider running a second test instance of the DB in the cloud?
This is using the test instance :) The issue replicates both on prod (cloud) and test (cloud).
But not locally. So a nice 30 minute deployment pipeline run to test if your fix worked, since we are firewalled from direct DB connections from local dev machines, even for test instances.
SOP though..
There's a spcetrum between 'all the edge cases' and 'most of the edge cases'. A web app for a blog is not exactly like an automat onboard the JamesWebb telescop...
it's not possible to predict everything, so instrument, let your software be loud, and listen to it.
Can your GUI app works on a Windows 95 with Polish as the system langauge while using a Chinese input method, and the user holding Alt all the time? Probably not. But the question we should ask isn't how could we make it work, but why the hell do we need to support this use case?
I don't even think it is necessary to ask that question. The only question that should be asked for something like this is "How do we handle all unsupported use-cases?"
Because then it becomes simpler, when an edge-case causes the software to freeze, to detect for that edge-case and hand it off to the "not supported" handler.
In the best case scenario, we simply detect whether the use-case is supported and then either proceed or hand control to the not-supported-handler.
In the worst case scenario, when the bug report comes in, we don't even bother trying to reproduce it, we just add a general check for it and move on to the not-supported-handler.
In this particular case, the detection can do any one of the following:
1. Check for english, and if not, display "unsupported language". 2. Check that input language and system language match, or display unsupported". 3. Check that the OS is supported, display "unsupported OS" if not. 4. Check that the input is valid (i.e. no special codes, whether by holding down halt or otherwise), or display "unsupported input".
Whether the spec is narrow or wide, the developer needs to do the work to ensure that the user is running within spec.
Not checking results in more "bugs" that are, as you said, use-cases which shouldn't be supported anyway.
Until you find out that your operating system handles 95% of unsupported cases in one way, then uses a hidden API to deal with the weirdness of other languages and the unsupported case isn't detected in that last 5% of languages. Of course that never came up in testing because who uses a hebrew/japanese combination and now the error message being returned by your application has nothing to do with the actual problem.
Your worst case scenario is just the common edge case bug handling that support/QA/dev's handle every day.
define "bug free". In Python, I've been reimplementing monads recently. It's such a shame that Python still doesn't have Null/None propagation. After each obtained result and before using it in the next chain, I have to run a series of sanity checks (is it Null or not, etc.) which should be resolved automatically by the language. Alas, most people don't care.
Something like this would be nice:
result =? foo(bar :? str)
meaning that foo should receive a str bar, but maybe bar is not str. Then foo should return something, but maybe it returns None (the =? part).Which is to say that inovation happens only when you try to do stuff just a little different each time, so I’d say that code reviews as currently implemented at those big organizations is against long-term programming-related innovation.
This gets missed by so many developers, once you change your mindset on this, you'll find you write better software.
One of the questions to ask when writing code is "how long will it take to discover if this goes wrong?". Make it quick to find, let someone else in the future deal with the imperfections.
I'm not saying don't try for perfect code, I'm saying not having written perfect code isn't a problem and it isn't a failing. code evolves to be stable, it is not born that way.