Software disenchantment
tonsky.me
tonsky.me
If its not done its because there is no money in it. In fact the opposite.
The counter-incentives to wasting time on high quality software are numerous and affect all sorts of teams. VC funded startups must get to market first or die. Fake-it-till-you-make-it is their religion. For more mature organizations too, cost and bloat is not an issue. Its a feature. The bigger the team more prestige for the managers etc. The costs are passed on to clients anyway.
How come "ruthless market forces" don't rectify this wastefulness? You'd think that codebases of superior quality will earn the keys to the kingdom. They might, eventually. In a competitive environment that is less prone to pathologies, hypes etc.
Everyone claims to care about the environment until it impacts them even slightly. It's not even hard/time consuming to write good code. People are just overwhelmingly selfish and lazy.
Software devs consistently contribute to the environmental problems that many software devs then complain about and pretend is only a redneck issue. The reality is that we have an incredibly serious idiot issue and there isn't a solution due to the scale of the problem and the corruption preventing meaningful change.
An article the other day pointed out the problem well as well. Though it was related to the increasing lack of people who understand the code underneath the current flavour of the month bullshit framework.
It doesn’t help that schwabists try to provide indexes such as “Java consumes more than JS”.
This kind of sentences, measuring the immeasurable like a square meter takes more energy than a liter, communicates “We’ll dominate you with power while understanding nothing of what you do, and tax you for using Java”. I bet it’s Facebook’s PHP lobbyists who came up with that.
If heating is a problem, then by all means, tax CPU time. But I already know the tax won’t matter because software provides such an immense value to society. We already pay average engineers $800 a day! But we shouldn’t try to get rid of a language.
If they knew what they were doing, they’d certainly ban NPM. But of course there are already GitHub actions and Sonar extensions publishing the CO2 consumption index of Java programs...
But certainly Microsoft shouldn't be allowed to carelessly use a public, scarce resource like freshwater on such a scale as they did during a drought in order to train a model[0] they didn't have a use-case for yet? They should at least pay for the use of that resource to help the local community that now has to deal with the consequences.
The company claims it will "replenish more fresh water than it consumes by 2030," some how... but that's too little too late. And whose to say they will keep that promise? There's no consequence to them if everyone forgets about it and they never follow through. No better time than the present to course-correct.
Resource-extraction companies are like this too. They'll exploit the environment and pollute like crazy unless they are forced not to. They will fight tooth and nail to avoid regulation since that slows or limits profits. But they don't care about people or the environment. Neither do technology companies.
Small gains in efficiency at the level of user-space code has been shown to translate into marginal gains in profits in domains such as ads and securities trading. Data centres also look for efficiency gains here to reduce their operating costs where possible. However I suspect we're getting close to the limit here in terms of gains and motivation. There is still a significant amount of, "throw more machines, air conditioning, and fresh water at the problem until it goes away," kind of thinking since the environmental impacts of those decisions have no consequence to the ones making them.
There's no need to measure the energy usage of the JVM if it's doing useful work. However there probably should be more guidelines for where it's appropriate to set up data-centres and taxing them for the resources they use and pollution they create.
[0] https://futurism.com/critics-microsoft-water-train-ai-drough...
This bears repeating. It's the disease that has consumed software and is making all modern software the worst possible version of itself.
I think it's the VC funding model which has driven the industry this way. Startups get millions in funding, then it's a race to make enough money to pay back those investors which leads to this. The companies have to squeeze dollars from their app as fast as possible which means anything that doesn't have a ROI metric attached to it will not get a second of anyone's attention.
they don't care because their _users_ don't care.
I find these discussions are always led by engineers, shaking their fists at clouds. nobody cares! it doesn't make any money so you're just whining into the void.
Except that's not true. Users do care they just don't have a choice in the matter. I have listened to many, many laypeople who have expressed frustration with software. They may not be able to articulate it to the extent that the quote does, but when they're stuck on 3G and they need to load a webpage that keeps timing out they get frustrated even if they don't know its because of the footprint, it's a poorly made SPA, or whatever.
I respectfully disagree. I think the users care, but they don't make their own choices - their choices are made for them by people who don't care!
Was MS Teams chosen by their end-users? Nope.
Come to think of it - was Slack chosen by their end-users? No, again.
End-user's aren't given an option, usually:
1. For B2B the choice rests with one (or a few) people.
2. For B2C the choice is made purely because some product got some traction for reasons unrelated to its quality, and that was enough to force the rest of the users to follow or be left out of the network (Slack, Facebook, major shopping sites, etc).
The majority of end-users did not exercise any choice.
Indeed, the very existence of so many frameworks is also very easy to blame on errant engineering.
When I was in university (a long time ago, shortly after the big bang :-)) the informal motto of the computer science faculty and students was Computer Science: Solving Yesterdays Problems, Tomorrow!
Now that I think about it, I don't find it that funny anymore.
This is another example of Scott Alexander's Moloch: https://www.slatestarcodexabridged.com/Meditations-On-Moloch
"companies in an economic environment of sufficiently intense competition are forced to abandon all values except optimizing- for-profit or else be outcompeted by companies that optimized for profit better and so can sell the same service at a lower price."
Exactly my thought. Incentives are not aligned. There are industry sectors where performance and correctness have value. If you care about the software craft in the same way as the aithor (as I do!) then the best way to enjoy work is to move to such industry sectors.
Except car manufacturers.
That said, this is probably what any big enough company would do. So your point still stands, maybe car manufacturers are no different.
I can only speculate about other sectors where it might make sense: - Hardware synthesis (i.e. the software used to design silicon chips); - Aerospace; - Defense; - Smart city devices;
> Care to provide examples of such sectors? Thanks.
I worked for years developing munitions control software.
Never once killed anyone by accident.
An ideal world isn't one in which either the MBAs or the engineers win. It's one in which they coexist and find a reasonable balance between having more useful features than the competition and not expending too much effort to build and maintain those features.
I’m a software engineer, not an MBA.
YC is a VC firm which is a very specific context that demands things like revenue and growth to be so prioritized as to be implicit and core features of the working ideology. That's not really a good model for software engineering when it comes to social benefit -- it prioritizes something else. It can demonstrate incidental social benefit but that's not actually an incentive that's built into the system that YC operates in and reflects internally.
There are Scotsmen out there, they're just not part of this discussion. That doesn't make anything I said a "no true Scotsman" argument.
https://github.com/id-Software/DOOM
Shall I prepare the postage for the letter in which you'll call John Carmack an MBA? Should we send another to Chris Sawyer? I heard he didn't even write a formal design doc for Roller Coaster Tycoon!
Nowhere did I say sloppy code is the problem, what I said was justifying it in terms of profitability is the problem. There's a difference between cranking something out because you're excited to show it and rushing through an implementation because of this or that externally defined money-based KPI.
Is it correct to build a piece of software that runs 50% slower, but can be built in 6 months instead of 12? The answer is "it depends" and good engineers will seek to understand the broader context of the business, users, and customers to make that decision.
Huh? Unit tests are critical to be able to perform a major refactor without breaking everything.
Of course there are always exceptions, and testing philosophy should bend to the goals of the organization, not the other way round.
And if a five line bash script is a more suitable test than a unit test in the same language as the application, then that's what you should do. Assuming you have a good way to automate it as part of an automated build and deploy process, of course.
Except by the end it hardly mattered any more. RF modulators and tuners had gotten so good, that perfectly adequate video resulted from the RGB -> composite -> RF -> composite -> RGB chain. Bloat, but who cares?
In an automobile, the "proper" way to charge a phone is to have a 12VDC->USB type of adapter plug. The "bloat" way is to have a 12VDC->120VAC inverter and then plug the phone's existing wall charger into that. More circuitry, but it gets the job done and it's cheap.
If you like designing electronic gadgets, the "proper" way to flash an LED is two transistors and a couple of resistors and capacitors to build an astable multivibrator. The modern way is to program up a small 8-pin microcontroller. A CPU running thousands of lines of code just to blink an LED? Who cares.
If your computer/tablet/phone are reasonably recent it's the same for software. It's only when your gadget is a few years old that you really see the bloat as formerly performant software "degrades" in later versions.
Eh, no it didn't. That would just look horrible.
Look outside software and see what things has been deemed quality and why.
Usually the people doing quality make very few comprises and often they don't do it on purpose.
Quality solely starts with yourself. Only you can guarantee within your own merits and experience what quality is.
Explaining quality is thereby difficult because it is so determined by the personal traits and experience.
But short-term interests go explicitly AGAINST that. If I start demanding +20% more time to deliver quality the company will likely start a campaign to replace me in 3-6 months.
From one age (or burnout quantity) we prioritize stability. Ironically it's only then when we can truly provide the good quality but by that time we're much more risk-averse.
sighs
Oh well.
Microsoft Teams is one of the most buggy, unreliable pieces of software I know, but it's still the market leader in terms of share because of Microsoft's near monopoly of the office suite software world.
- slow, high-latency software
- poor resource usage slowing down the whole machine, including from unrelated software
- bad user interface design
- bugs
- intentionally bad/manipulative patterns
if the customers can't even really perceive what it is they are buying, it's not surprising that market forces aren't solving the problem.
i'm not a user interface designer or researcher so of course this could be totally wrong -- just an impression from informal observation
this is something that happens more widely in the use of resources: you build more highways and instead of relieving congestion you get more people commuting
[1] my open source and volunteer-built linux distribution (will not name names) routinely (like almost daily) prompts for GB sized system updates.
What we can do though, that perhaps VC funded companies can not as easilly, is alocate time to refactor code and deal with tech debt. In fact that is what we are currently doing and we basically pulled a handbreak on all new feature developement for 45 days to deal with our main tech issues. Ability to do this requires a long term thinking horizon. Very difficult to make that kind of investment if you expect to get acquired next year and tech debt becomes somebody else's problem.
Also worth noting, as long as the product is being actively developed it will aways have new bugs and issues. 'Perfect code' is achieveable only in a closed context scenario, where new features are not added any more. (which randomly bring this weird thought to my head, that the only human that does not do any mistakes any more is a dead one; perfection in human actions is only achieved in the absence of life... ok need to stop there)
Love a good philosophical tangent! Wish you expanded :)
the trouble, empirically speaking, is that this "longer run" is not close enough to weigh on decisions :-)
Open access by default. No passwords [1] or short passwords. Then insecurely stored passwords. Everything in plaintext. Input sanitation? Why bother, only I can input data, I trust myself. Don't get me started on telnet.
I suspect that's another reason why software is more bloated. We started noticing things, how they interact with each other. And once you see something, you can't unsee it. The edge cases we have to account for are growing, not decreasing. There's more hardware to support too.
I'm sure the whole process of writing performant code can be improved. At the same time the bar is being raised faster than we can (or want to) reach it.
1 - And now we're inching towards no passwords again.
The trouble with exponential curves is that a small difference in rates can create dramatic discrepancies.
We've done it a bit, Apple's little wrist-slap for slowing down the iPhones, for example.
We just need more of it. I know it's all anti-Libertarian or whatnot, but "more regulation" has worked quite a bit in the past and present. Just do that.
But the quality of the codebase definitely had less effect in the company’s success than you’d expect, like you said. The costs are just shuffled down to the customers and developers while everyone else gets rich.
Sure, that's valid. Though most of the world is not comprised of startups. That's mostly a USA thing with a few small exceptions out there as well.
> How come "ruthless market forces" don't rectify this wastefulness?
They do, though people mistake those forces for "incumbents with enough power to influence the market forces". So we're witnessing the reality which they dominate.
I had plenty of examples in my career where better code helped the company long-term but as we all know, there must be a leader somewhere who understands the tradeoffs and give a green light every now and then.
You're assuming that the people with this experience have a) successfully passed it on, and / or that, b) they're still coding.
We don't have an apprenticeship model in software development that would lend itself to such a thing. Each new crop of developers has to relearn the lessons in whatever new stack they happen to encounter the issues. It would be like each new generation of carpenters having to relearn their trade because the wood had entirely different characteristics every time someone went to use it.
That experience you mention applies to the general cases, but again, the people that have it may not be the ones doing the work hands-on any more.
I would personally put the low quality of our code more down to immaturity and lack of tooling.
Recently it came back to me. And with the old, 2017 vintage software on it, still worked as it did then. But before making it a kiddie computer, I installed FC38 and the current version of Chrome.
But Youtube videos were now "slide shows". No amount of fiddling with the settings made them play right. Finally gave up and changed the RAM from 2GB to 3GB - I just happened to have the right (laptop) memory card to do that.
And that brought it back to the old, barely adequate (720p fullscreen without noticeable skips) performance. 1.5x as much memory, an extra gigabyte, to do the same thing as six years ago.
"So get with the program and buy an adequate machine! Don't you know that 16GB is the absolute minimum to get anything done these days?" Sure - I have machines with 16GB+ in them. Even on the crappy machine though, Google Chrome is showing a memory footprint on the order of 30GB. I'm sure most of that is mmap'ed files; it sure isn't RAM. But 30GB. For a mostly idle web browser.
linux-vdso.so.1 (0x00007ffd353a6000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f852c4ea000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f852c4e5000) libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f851eba4000) libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f851ea69000) libnss3.so => /lib64/libnss3.so (0x00007f851e92b000) libnssutil3.so => /lib64/libnssutil3.so (0x00007f852c4b2000) libsmime3.so => /lib64/libsmime3.so (0x00007f851e8ff000) libnspr4.so => /lib64/libnspr4.so (0x00007f851e8bc000) libatk-1.0.so.0 => /lib64/libatk-1.0.so.0 (0x00007f851e892000) libatk-bridge-2.0.so.0 => /lib64/libatk-bridge-2.0.so.0 (0x00007f851e859000) libcups.so.2 => /lib64/libcups.so.2 (0x00007f851e7ba000) libgio-2.0.so.0 => /lib64/libgio-2.0.so.0 (0x00007f851e5e0000) libdrm.so.2 => /lib64/libdrm.so.2 (0x00007f852c498000) libdbus-1.so.3 => /lib64/libdbus-1.so.3 (0x00007f851e58d000) libatspi.so.0 => /lib64/libatspi.so.0 (0x00007f851e550000) libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f851e51f000) libm.so.6 => /lib64/libm.so.6 (0x00007f851e443000) libX11.so.6 => /lib64/libX11.so.6 (0x00007f851e2fb000) libXcomposite.so.1 => /lib64/libXcomposite.so.1 (0x00007f852c491000) libXdamage.so.1 => /lib64/libXdamage.so.1 (0x00007f852c48c000) libXext.so.6 => /lib64/libXext.so.6 (0x00007f851e2e6000) libXfixes.so.3 => /lib64/libXfixes.so.3 (0x00007f851e2dd000) libXrandr.so.2 => /lib64/libXrandr.so.2 (0x00007f851e2d0000) libgbm.so.1 => /lib64/libgbm.so.1 (0x00007f851e2bf000) libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f851e292000) libxkbcommon.so.0 => /lib64/libxkbcommon.so.0 (0x00007f851e249000) libpango-1.0.so.0 => /lib64/libpango-1.0.so.0 (0x00007f851e1e2000) libcairo.so.2 => /lib64/libcairo.so.2 (0x00007f851e0c6000) libasound.so.2 => /lib64/libasound.so.2 (0x00007f851dfb7000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f851df9c000) libc.so.6 => /lib64/libc.so.6 (0x00007f851dc00000) /lib64/ld-linux-x86-64.so.2 (0x00007f852c512000) libffi.so.6 => /lib64/libffi.so.6 (0x00007f851df8f000) libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f851df17000) libplc4.so => /lib64/libplc4.so (0x00007f851df10000) libplds4.so => /lib64/libplds4.so (0x00007f851df0b000) libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f851deb2000) libavahi-common.so.3 => /lib64/libavahi-common.so.3 (0x00007f851dea4000) libavahi-client.so.3 => /lib64/libavahi-client.so.3 (0x00007f851de8f000) libgnutls.so.30 => /lib64/libgnutls.so.30 (0x00007f851d800000) libz.so.1 => /lib64/libz.so.1 (0x00007f851de75000) libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f851de6e000) libmount.so.1 => /lib64/libmount.so.1 (0x00007f851de27000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f851dbd5000) libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f851db03000) libXi.so.6 => /lib64/libXi.so.6 (0x00007f851de15000) libXrender.so.1 => /lib64/libXrender.so.1 (0x00007f851daf6000) libwayland-server.so.0 => /lib64/libwayland-server.so.0 (0x00007f851dae0000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f851d400000) libXau.so.6 => /lib64/libXau.so.6 (0x00007f851de0d000) libfribidi.so.0 => /lib64/libfribidi.so.0 (0x00007f851dac0000) libthai.so.0 => /lib64/libthai.so.0 (0x00007f851dab5000) libharfbuzz.so.0 => /lib64/libharfbuzz.so.0 (0x00007f851d729000) libpixman-1.so.0 => /lib64/libpixman-1.so.0 (0x00007f851d67d000) libfontconfig.so.1 => /lib64/libfontconfig.so.1 (0x00007f851da66000) libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007f851d335000) libpng16.so.16 => /lib64/libpng16.so.16 (0x00007f851da2d000) libxcb-shm.so.0 => /lib64/libxcb-shm.so.0 (0x00007f851da28000) libxcb-render.so.0 => /lib64/libxcb-render.so.0 (0x00007f851d66d000) libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f851d257000) libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f851d655000) libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f851d64e000) libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f851d63d000) libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f851d636000) libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f851ce00000) libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f851d622000) libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007f851d125000) libidn2.so.0 => /lib64/libidn2.so.0 (0x00007f851cdaf000) libunistring.so.2 => /lib64/libunistring.so.2 (0x00007f851cc2a000) libtasn1.so.6 => /lib64/libtasn1.so.6 (0x00007f851d10d000) libnettle.so.8 => /lib64/libnettle.so.8 (0x00007f851cbd7000) libhogweed.so.6 => /lib64/libhogweed.so.6 (0x00007f851cb94000) libgmp.so.10 => /lib64/libgmp.so.10 (0x00007f851caf1000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f851cab9000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f851ca1d000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f851c9f1000) libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f851c942000) liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f851c91e000) libcap.so.2 => /lib64/libcap.so.2 (0x00007f851d103000) libgcrypt.so.20 => /lib64/libgcrypt.so.20 (0x00007f851c7e2000) libdatrie.so.1 => /lib64/libdatrie.so.1 (0x00007f851d0fa000) libgraphite2.so.3 => /lib64/libgraphite2.so.3 (0x00007f851c7c1000) libxml2.so.2 => /lib64/libxml2.so.2 (0x00007f851c637000) libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f851c624000) libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f851c616000) libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f851c5f0000) libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f851c5cd000)
Modern toolchains are all about "not reinventing the wheel" -- but when each dependency has picked a different version of said wheel, just pulling in a few dependencies leads to 6 different implementations of the same low-level features.
Most RAM usage increases in Chrome have come from advancements in the sandboxing architecture. Shared memory and process space could be used to attackaand bust out of sandboxes, so more isolation was added. I'm sure there are some more useless features leading to a jump in RAM usage as well, but the really big ones always seem to be the fact Chrome spawns a new, independent process for every tab/extension.
I've also noticed how much impact ad blockers have these days. With the web becoming ever shittier, effective adblockers have become harder to make and need more resources to do their job.
Software doesn't get slower just to make your day harder. In many cases, slow software is a result of replacing dangerous hacks by good implementations and changing requirements. FLV videos just don't cut it anymore, and I doubt h264 will be around in five years with h265 and AV1 making it's way to more and more devices.
Oh, and the same applies to the original blog post, too.
The entire "there was no usable encoder and no hw decoder for years" thing didn't help and even now it's still all slow and complex, who has time and money for that?
AV1 is just too complex for what it produces in comparison with the good old h264 or vp9.
h265 hardware decoding came out in 2015 with Nvidia's 9xx series, while AV1 took until the unaffordable Nvidia 30xx/Intel Xe/RDNA 2 generation to become available. Encoding support took even longer (RDNA3/Xe 2/Arc/40xx). In a few years, I'm sure it'll be as popular a format as h265 is today.
Simple example, I sold my car to Carvana the other day and just baaaarely pulled it off using Chrome and Firefox. In Chrome the upload image wizard would get a JS exception. That part of the app miraculously worked in FF, but virtually the entire rest of the site was mired in issues as it's obvious Carvana devs don't test in FF. I pulled off the transaction by bouncing between the two.
Even worse, most non-technical people think they did something wrong when they encounter a bug.
Software that is bloated and slow but stable and rock solid? I'd gladly take it at this point.
There are still computer systems designed with high reliability and accuracy. See flight control systems.
New technology typically doesn't work on duct tape and bubblegum. So it has to be good. Current technology is going to be just right enough to work.
It can be hard to tell what is "duct tape" and what is "speed tape" in software these days. An aircraft mechanic doesn't need to know the structural differences between the two - just use speed tape to be safe. Similarly, a pure programmer doesn't have to know the difference between ufw and Windows Firewall - just use the latter and move on.
However, an engineer (mechanical or software) better understand the differences in both situations
I understand all the points about financial costs and opportunity costs and pragmatism and the rest, and I partially agree with it, but it's hard not to sometimes feel like we've accepted living in a half built world.
Not testing on Firefox just makes sense given how niche it has become. Not worth the effort to go beyond Chromium.
The number of vehicle software updates are staggering.
Then something got pushed over the cliff. Windows 10 and the UWP...like seriously WTF!? Satan's very own dumpster fire.
And it's not like things have gotten any better, now I'm an adult with young children and if one of them gets their hands on my phone or laptop, they seem to be just as reliably be able to lock up, crash, freeze modern devices all the same. These kids are not physically damaging the phone in any way, they're just pushing buttons too quickly or in unexpected orders. That's the state of modern tech that we're in.
To be honest, I can understand why this hasn't been fixed. As mentioned in the article and throughout these comments, we've just come to expect to need to restart every now and again. In this case, people are likely to blame such a problem on the child, and a restart fixes the issue anyway. I just would've hoped for better by now in the lifecycle of these operating systems.
I don't work for anyone right now, but I do have a "work" machine. This machine is beefy.
But I still run Neovim and tmux instead of an IDE. [2]
I don't run a typical Linux distro; I use a heavily-modified Gentoo, and that includes using OpenRC over systemd. [3]
I don't use a full desktop; I run a TWM called Qtile. [4]
All of this is so my machine is not bloated. When my machine boots up, and I just barely log in, it is running only 40 processes (including the terminal and htop I use to check).
As of right now, I'm engineering software. Truly engineering; I am spending the effort to effectively mitigate all of C's problems, while keeping the software lean and fast. I hope to someday build a business on that software.
I guess I'll see if there even is a market for non-bloated, sleek software anymore.
[1]: https://gavinhoward.com/2023/02/why-i-use-c-when-i-believe-i...
[2]: https://gavinhoward.com/2020/12/my-development-environment-a...
[3]: https://gavinhoward.com/2023/06/an-apology-to-the-gentoo-aut...
[4]: https://gavinhoward.com/2023/09/lessons-learned-as-a-user-3-...
Yep
Think about it. Is there any widely-deployed OS not written in C/C++? Any web browsers? Spreadsheets? CAD software? Text editor?
Surely you understand that your argument is disingenuous, right? Nobody wants to start over a new OS or a browser in another language due to the huge costs that no corporation nowadays is willing to shoulder (due to their own interests). Otherwise a lot of people would very definitely write OS-es and browsers in Rust, D, V even, Zig, Nim and a good amount of others.
C/C++ were there first, that's all there is to it, it's that simple.
> ... I use a heavily-modified Gentoo ...
Need not say more :)Besides, I struggled with sysadmin-type tasks until I bit the bullet and installed Linux from Scratch and then Gentoo. It was one of my best educational investments.
"I am going to build the strongest, lightest bridge in the world" is a marvel. "I am going to build a light-enough strong-enough bridge for a cost my client can afford" is engineering.
But a sign of considering tradeoffs is that every project seems to be just a little different because every circumstance is just a little different.
When you have a software monoculture or monocultures, it's likely that tradeoffs are being ignored.
For me personally, I am banking on having multiple business customers for my software. If I consider the cost amortized, I can spend a little more to engineer something better.
But yes, it still has to be fit for purpose. My customers will provide a document that explains what they want to do with my software and on what platforms. If I sign a contract, that means I am committing to supporting their purposes on those platforms.
Avionics. Air traffic control. Industrial control. Automotive software. 911 dispatch. Medical instruments. Medical information. Military command and control. Mechanical engineering analysis software.
Lots of software can kill people.
that's what i was trying to draw attention to.
Can you expand on that?
Which exact problems of C's are you working on solving? Do you mean the language itself (writing a new dialect of C), or the ecosystem (e.g. impossibility of static linking with glibc)? Or something else entirely?
My blog post about C has a blurb about how I'm really writing in a partially memory-safe portable dialect.
I have bounds checks, structured concurrency (to mitigate use-after-free and double-frees), and a bunch of other stuff.
Actually, I had written more about Rust and Ada, but then I read your blog, and it says you like C better anyway because you find it more fun, so nevermind.
You might also like to use D in its "Better C" mode, which at least offers bounds-checked arrays and sliced, as well as some other features, while being very similar to C.
Try supporting unicode
After I get to MVP and actually try marketing, we'll see what happens.
Making something people want enough to pay for is very difficult; if you are trying to do that while also imposing a bunch of other constraints on yourself that have no clear marketing benefits, your odds of success go down a lot.
Engineering excellence can sometimes be used successfully as a form of marketing in itself and you could well pull this off, as your content is super engaging and well-written.
But I would suggest to every engineer to consider Chesterton’s fence. Why is all the winning software in every category slow and bloated and seemingly unconcerned with engineering excellence? Is it because everyone involved, the engineers that build it and the customers that buy it, are all technical philistine morons? Or is it because the products that win in the market prioritize… winning in the market, and all their competitors that don’t prioritize that for whatever reason fall by the wayside?
I'm all for quality engineering. I'm just saying that if your whole plan for a new product is "quality engineering", then you have no plan at all. The horse needs to come before the cart.
What you're describing is a tragedy of the commons from the perspective of social and civilizational benefit. I agree that's what it is, but I think we should be more careful before justifying it.
> But I would suggest to every engineer to consider Chesterton’s fence.
I agree.
In fact, I believe I have considered Chesterton's Fence; I have a plan.
I'd like your opinion on my plan.
> Making something people want enough to pay for is very difficult.
Yes, absolutely.
To fight this, I have spent years, 3.5 years, figuring out what people hate about build systems, and I have designed mine to address those.
While that doesn't guarantee success, I think it may improve my odds. Do you agree?
> That is: builders who prioritize marketing outcompete those who prioritize engineering quality.
Yes, and it sucks.
I hate marketers. I hate marketing. I hate the fact that I'm going to do it. But I have to.
So my marketing with be focused on giving people something for just paying attention.
> Engineering excellence can sometimes be used successfully as a form of marketing in itself and you could well pull this off, as your content is super engaging and well-written.
Thank you for your compliment! I hope so, and my plan is to emphasize this.
I'm going to post four articles on HN, each a week apart, and each will be designed to give readers something substantial, with a blurb about marketing at the end that will be clearly marked as marketing.
* The first will be new FOSS licenses designed to better protect contributors from legal liability.
* The second will be a post on language design and psychology.
* The third will be a deep dive into Turing-completeness and what it means.
* The fourth will be the source code as a Show HN, along with an offer for early adopters.
> Or is it because the products that win in the market prioritize… winning in the market, and all their competitors that don’t prioritize that for whatever reason fall by the wayside?
It's awful, but you are right.
So this marketing push is all I will do for four weeks: preparing and posting, and responding to comments. This is when I will "prioritize winning in the market."
Does this have a chance of working?
It's a start for sure. But personally I'd suggest changing your mindset a bit from the idea that you'll come out of the code cave for a month to grit your teeth and do marketing. Granted, this is much better than just staying in the cave. But really to run a successful business I think you need to accept at a deep level that marketing, making money, and growing the business is now your main job, and you will permanently need to spend at least as many thought cycles on that as you do on programming.
To wit, while posting those articles and a Show HN sounds like a good plan and you should definitely do that, what will you do if they all fall flat and get no traction? It's a distinct possibility, and I hope you won't just give up.
I'd think more about what you're going to do every week for the next year to get users rather than putting all your chips on an HN launch that may or may not pan out. Even if you do rock the HN launch, you're probably going to have the "trough of sorrow"[1] to contend with after, so I'd think more about how you can make marketing a repeatable part of your rhythm in the long run.
1 - https://andrewchen.com/after-the-techcrunch-bump-life-in-the...
> while posting those articles and a Show HN sounds like a good plan and you should definitely do that, what will you do if they all fall flat and get no traction?
You got me. I was planning on giving up. :P
I am in a place where the only cost to switching projects and trying again in three years is the opportunity cost, so because I'm bad at constant marketing, that's what I was going to do if I got zero traction.
If I got only some traction, I'd weigh my options.
I was only going to worry about long-term weekly marketing if the launch went well enough.
Because I'll be frank: I have no idea how to do constant marketing that doesn't bother people or waste their time. If I would waste their time, I'd rather just throw my own time away and switch projects.
> Even if you do rock the HN launch, you're probably going to have the "trough of sorrow"[1] to contend with after
Good blog post, and yes, I agree. I am expecting the trough as I build up the MVP.
If you haven't gotten it in many users' hands yet, it might be a good idea to try recruiting like 50-100 users first, either one-by-one through email reachouts or in smaller communities where it's less hit-or-miss, like niche subreddits. If some of these users like the product and stick with it, start giving you feature requests, etc., that tells you that you're on to something. Conversely, if you can't get even a small group of users to try it and stick with it using that approach, it's much more of a negative signal than a failed HN launch and probably indicates that something needs to change.
Whatever route you decide to take, I wish you the best with it!
Also:
"I have no idea how to do constant marketing that doesn't bother people or waste their time. If I would waste their time, I'd rather just throw my own time away and switch projects."
That's noble of you, but I would cut yourself some slack. Ideally you would market in a way where you don't bother people or waste their time, but getting users often requires trying things where you risk getting close to that line. Sometimes you might cross over it, but that's just something to learn from.
Trying to market a product while never bothering anyone the least little bit is a bit like trying to be a comedian without offending anyone or to find a romantic partner without enduring some awkward dates. I think it just goes with the territory.
I'll think about what to do.
I think patio11 is someone who has used a similar marketing strategy to great success. People hire him because of the quality of his writing demonstrating his understanding.
I also think I can't replicate patio11's success! He's a much better marketer and writer than me.
Not your parent commenter but I wouldn't agree, no. Build systems are one of these things most companies want to setup once and want to never deal with them again, and only do so if they have zero choice.
`earthly.dev` had an article some weeks ago that addressed why one of their products never took off even though it's really good and addresses grievances in the space. The TL;DR was that existing customers of other CI/CD tools did not want to migrate to a new system, especially since it doesn't offer a migration from their existing solution.
Here it is, hope you find it insightful: https://earthly.dev/blog/shutting-down-earthly-ci/
1. They are extremely aggressive about coming to market fast. That's a good thing, yes. 2. They then let the project ossify because they view development as a cost center. Which is a bad thing. 3. Their endgame after being successful enough and can afford enough lawyers, they start proactively buying or shutting down potential competitors.
The "marketing wins over quality (and slower) engineering" does apply, yes, but not throughout the entire lifecycle. It applies only in the very first phase.
Your perspective is interesting because I'm old enough to remember when the C Language was considered bloat compared to just writing it in assembly language.
Examples of 1980s programs in assembly was WordPerfect, Lotus 123, MS-DOS 1.0. SubLogic Flight Simulator (before Microsoft bought it) was also in assembly.
Back then, industry observers were saying that MS Word and MS Excel being written in "bloated" C was a reason that Microsoft was iterating on new features faster and porting to other architectures sooner than competitors WordPerfect and Lotus 123 because they stayed with assembly language too long. (They did eventually adopt C.)
I see this "bloat-vs-lean" tradeoff in my own software I write for my private use. I often use higher-level and "bloated" C#/Python instead of the leaner C/C++ because I can finish a particular task a lot faster. In my case I'm more skilled in C++ than C# and prefer leaner C++ executables but those positives don't matter when C# accomplishes a desired task in less time. I'm part of the bloated software problem!
It's all tradeoffs; and finding the sweet spot for every particular insurance.
I believe the article is complaining that people just blow past the sweet spot.
In your case, C# is the sweet spot. In my case, I expect customers will want speed; I'm building an interpreter for a programming language.
Languages like C brought a massive benefit to accessibility. Devolving “software is slow” to “yeah but C vs assembly” is such a ridiculous crutch argument. Assembly is not remotely approachable to the majority of programmers. C, rust, zig, c++, Java, C# are all approachable languages that are fast and have great fast libraries and frameworks to work with.
All I can see in the “I can finish the see sharp program faster” argument is that “python vs c++.jpeg” from the 2000’s where half the python was importing libraries, but they wrote the C++ from scratch, and everyone who knew nothing about C++ moved this image around like it was some hilarious joke of C++.
Both perspectives are correct for their respective times. Compilers were much dumber in 80. These days your GUI desktop program written in assembly language would probably run slower than written in C and compiled with modern gcc O2.
The problem is greed - i.e. capitalism. The blog mentions Electron and therefore Chrome and JavaScript. They are awful combination and allow companies to save on programmers. Programmers which handle C, C++, Rust or Python are a small group. Java, C# and JavaScript consume more resources, allow using a lot more stuff quicker (like a drug) and most importantly are forgiving mistakes. So the industry decides to waste the resources on our computers because they don’t need to buy and maintain them. The customer pays twice, for the software and the next computer with more soldered main-memory. The key point is - the software companies don’t pay for hardware or the environmental damage! I’m doing myself a little JavaScript and some Java. Efficiency? Nobody ask for that and I should not spend time on it. There is now law stating that managed languages need to waste resources but a side-effect.
Remember Steve Jobs? I don’t appreciate what Apple does. But he banned Flash for a reason. Resources! Okay. Also bugs. And for the same reason they should ban Electron. Apple devices run faster with less resources because Apple saves on hardware. Why build devices with huge batteries, when you can achieve more runtime with less material and take the same money? The EU needs to enforce side-loading on the iPhone. But I also think Apple should be allowed to keep Blink (and therefore Electron) banned from AppStore. I don’t want see my battery dying because some corporate manager decided to drain it. But if you need Blink? Side load.
They eliminated the unappropriate “desktop metaphor” from Windows 95 and the “system tray”.
The negative side is that GNOME often removes options or hides them - which drives away experienced users (the people needed to pull in new users) and some developers to forks. The are right to not support every bewildering option but the needed ones must in place despite the UX people don’t use them itself.
https://ometer.com/free-software-ui.html
Some of this is right. Do stuff automatically right and don’t provide unneeded options to avoid complexity. Some not! Also provide required preferences e.g. “Do not suspend on LID close” because some people don’t want that! The GNOME people assumed it was needed as option because of problems with suspend (S3) in the past. Maybe people used it to bypass issues but that isn’t the use case of the preference. Another thing is “When you’ve five clock applets” I want to know what is missing from the first one which made all the others necessary. GNOME learned that people don’t need an “Emacs” as UI-Shell but somewhat went into the other extremes.
PS: And GNOME just looks good by default. I don’t need themes because it is fine.
For me... I don't notice any slowness or excessive battery drain in VS Code, so I just use that. Perhaps there's something deeply wrong with my psychology, but I'm just not very interested in simplicity for its own sake. It's cool, but not an approach I'd want to use every day in real life.
I wonder how much of this is just because when a project manager comes along and says "as a system administrator, I want to be able to log all of the keystrokes of the users and reports who's slacking to the boss", you say, "ok, that feature will take about two weeks to implement" and they can't argue with you because it's C so they just go away and leave you alone.
The other key trait of the article was cherry-picking data and over simplifying domains. Several times the article alluded to the emotional plea that "what could the software possibly be doing that takes up that time/space" (my paraphrase) but it didn't place any serious attempt to answer that question, using their lack of provided answer as if it were an indication of an invalid answer and comparing various bits of software that do not have feature parity looking as if their only practical difference were performance. (Edit: Updated wording of previous sentence to be more clear.)
There's definitely alot to be said about how software could be more efficient as well as the social, environmental, and business costs of inefficiency, but there is also much to be said about how modern software empowers people that otherwise might not be able to write anything to write something "bad" that does what they need or to discuss how modern software developeres tend to aim to be "fast enough" in the way that an structural engineer would choose "strong enough."
There's much rich debate to be had, but this article didn't include it, instead going for an emotional rant, and failing to engage with actual reason. There is, in my opinion, truth to parts of the argument, but the article made itself clear that it didn't want a discussion.
The gist is that if your code takes just a couple of seconds to complete on your fancy M1 Mac, there will be a pretty big chunk of your potential audience who will have to wait for minutes (and there's that surprising character trait in many non-technical users that they simply accept such bullshit, because they don't know that performance could be drastically improved without them having to buy new hardware).
But unless devs test their code also on low-end devices they will be completely oblivious to that problem.
And the actual problem isn't even the technical aspects, but that some devs are getting awfully defensive when confronted with the ugly truth that their code is too slow and start arguing instead of sitting down with their product mangager and making time for some profiling and optimization sessions to see what can be done about the performance problems without having to start from scratch.
Is it a problem or are those people simply not worth serving?
And sure, they’re not worth serving, as long as you’re not worth their money. Meanwhile a competitor will.
Don’t be fooled by the browsers. Most products aren’t browsers. And if you don’t snap up the long tail, someone else will.
Really annoying how the author brings up counter points and comparisons but does not deeply engage with them, as if they're absolute truths and only rhetorical, when they're far from that.
If that was all, it would've been fine... if he was only listing bugs and saying he's tired of crappy software. But he has framed the article in a way as if he's describing the "why" and how the problem can be solved. In fact I've been following the author and he has a place where he lists all bugs he finds in software, and that in my opinion is a great initiative, but this article just opens too many threads and tangents and only appears to explain the root cause.
I could come up with a few examples like:
- trying to compare cars, buildings, and planes with software and not diving deeper into how much different they are and why. - or saying everybody seems to be ok with inefficient software without diving deeper into why everyone's ok with it. - or mentioning a tweet about a guy who spent more time trying to make something faster than he will ever gain back without going further into if it's a good/bad thing and why.
> If you feel all his points either superficial or wrong you could easily come up with counter arguments better than author.
I never said his points were superficial or wrong, just that he does not deeply engage with the threads he opens up. For that reason, I have no counter arguments to come up with, since he is just complaining about his issues and also does not come up with a good solution as such. Of course everyone would like nicer software, that's not new. Why is software different than other industries in the first place? Is it worth improving it? What are the trade-offs? What is the effort required at scale? What would we lose if we made software more like manufacturing? What would we gain? If he knows a path forward, does he have a better way to express it than the last "manifesto" paragraph? Etc.
But it is the truth, and all we have to do is simply look at software from the point of users.
What device did You use to write this comment? Iphone4, or 14? What device do You use as your workstation, some pentium with 4gbs of ram?
Heck, even going outside the software itself, but to related branch - What network did your device talked to servers? 5G/fiber counted in hundreds of Mbps or 2g counted in few kbs?
At the end of the day, actions speak louder then words. And you can pretend all You want that "wanting faster software" is unproven axiom, but if the axiom is followed by literally all of society, it might as well be taken as truth.
...especially since it originates from the exact same place as the "developer time is worth more" one. Only difference is who's time we are saving
If half of society is speaking a new language AND an old language, it doesn't really matter if the old language is superior. You need to be able to speak the new dialect just to navigate society, even if the new language only exists as a mechanism to differentiate the new generation from the old.
There is no evidence what-so-ever that “performance trades with developer time”. 99% of the time, reasonable performance is a skill issue, not a developer time issue.
In actual fact, if you look at “clean abstractions” and other nonsense, you can see that higher developer time actually seems to equate to lower performance. As we all also know, the best indicator of bug count is lines of code, so adding in all these abstractions that adds lines of code not only make code slower, but also results in more bugs.
That is to say, all current evidence points to the exact opposite of their claim:
Higher dev time = lower performance and more bugs (assuming higher dev time is coming from trying to abstract)
I think this is reductive. There are lots of things people can do in Python that would be slower to write in C, and no amount of skill is gonna close that gap.
> In actual fact, if you look at “clean abstractions” and other nonsense, you can see that higher developer time actually seems to equate to lower performance. As we all also know, the best indicator of bug count is lines of code, so adding in all these abstractions that adds lines of code not only make code slower, but also results in more bugs.
I understand the argument against bad abstractions, but what abstraction is adding lines of code? I think we can agree that most of the time abstractions are to reduce lines of code, even if they may make the code harder to read.
> Higher dev time = lower performance and more bugs (assuming higher dev time is coming from trying to abstract)
I'm sure there are lots of projects that are buggy with little abstractions.
Write python without import statements and then try to make this claim again.
C using libraries is often as easy, or easier than python with imports. You don’t get to let python use someone else’s prewritten code while C has to do it from scratch and then say “see”. It’s a false equivalence.
>I understand the argument against bad abstractions, but what abstraction is adding lines of code? I think we can agree that most of the time abstractions are to reduce lines of code, even if they may make the code harder to read.
I don’t agree with this claim. I’d say go check out YouTube video from people like Muratori who tackle this claim. We have no measurements one way or another, but if I was putting money down, I would bet that nearly all abstraction that occurs ends up adding lines instead of saving them.
>I'm sure there are lots of projects that are buggy with little abstractions.
I’d tend to agree that the evidence shows this, given that the vast majority (and it’s not even close) of bugs are measurably logic errors.
> I don’t agree with this claim. I’d say go check out YouTube video from people like Muratori who tackle this claim. We have no measurements one way or another, but if I was putting money down, I would bet that nearly all abstraction that occurs ends up adding lines instead of saving them.
We may not have measurements of the trend, but we can measure it on each abstraction fine. How many lines of code is your abstraction and how many lines would you have to duplicate if it wasn't for your abstraction? If you're not saving that much, don't make the abstraction.
Again, this isn't talking about maintainability. I still question the claim that less lines of code means less bugs, but I know it's a popular one. In my experience, it's the terse code that's doing a lot that winds up being buggy. I prefer things to be longer and explicit, so you're talking to someone that doesn't even like abstractions that much unless they're necessary.
> I’d tend to agree that the evidence shows this, given that the vast majority (and it’s not even close) of bugs are measurably logic errors.
I don't think this premise you propose is obviously false, but we have lots of evidence that memory bugs are the cause of most bugs.
The standard library is still a library. Python doesn’t provide very much as a language feature.
There are pros and cons to standard libraries. If we were talking about brand new C with not a massive community of quality libraries, then yeah. But we’re not. We are talking about a language with a half century of great libraries and frameworks being provided.
>memory bugs cause most bugs
Yeah no. Not even close. You’re thinking of Microsoft’s citation that 50% of their security bugs are memory safety, but that’s not 50% of all bugs.
Basic standard logic bugs are far and away the largest contributor to bugs.
The way we know this is that language choice virtually doesn’t matter. On the whole, developers write 20-30 bugs per 1,000 lines of code regardless of language, so memory errors simply cannot be the largest contributor to bugs.
No, it's completely different. When a programming language provides a solid way to do something, that becomes a standard and accepted API for doing that thing, and standards are really nice when working with others.
> Python doesn’t provide very much as a language feature.
Uh what. I don't even like Python that much but this is a ridiculous statement. If we're talking C vs Python, Python is able to deal with lists in extremely terse and memory safe ways and C has a bunch of error-prone ways to do that in 10x the amount of code. If you care about LOC so much, is this not a useful language feature? Aren't you essentially saying C is inherently buggier than Python?
> Yeah no. Not even close. You’re thinking of Microsoft’s citation that 50% of their security bugs are memory safety, but that’s not 50% of all bugs.
I wasn't, but it was 70% for the record.
> Basic standard logic bugs are far and away the largest contributor to bugs.
BS. Citation? By what metric? I would wager that almost all C programs have dozens of memory bugs in them whether the developers want to admit it or not.
Ever read a security audit of software before? It's never "Oh you forgot to filter this array." It's buffer overflows and poorly allocated variables.
> The way we know this is that language choice virtually doesn’t matter. On the whole, developers write 20-30 bugs per 1,000 lines of code regardless of language, so memory errors simply cannot be the largest contributor to bugs.
Again, citation? You dismiss a Microsoft security report because that's "just one company" (the biggest company) and then you say this?
It's almost like you're saying "There's more logic bugs than memory bugs in memory safe languages."
Because it takes time to skill up.
And also, if you put higher bar on require skill level, you inherently get less developers, which means more work per developer which then converts to time issue. Obviously it's not a one to one, because great dev will spend less time doing good job then a clueless one making a mess, but still
Actually? An old iPad on WiFi that is stationed on the other side of several walls.
Honestly, a lot of people don’t mind waiting a second for actions to complete. (For some of us, it’s the only pause we get to take during the day.)
There are enough low-end phone sales that we should be able to accept that some people really don’t mind taking an extra moment if it saves a dollar.
This really isn’t to say that software should be slow, but I think we should acknowledge that speed is not the sole value that users concern themselves with when using software. Many times it isn’t even a primary value.
Are you suggesting that maybe users (including you and me) should have to put up with painfully slow, stuttering software? I don’t see why his claim requires any justification - to my mind, it should be just as self evident as the fact that inflicting physical pain upon others should be avoided.
> […] modern software developeres tend to aim to be "fast enough" in the way that an structural engineer would choose "strong enough."
But they don’t aim to make software fast enough. My experience last week: Windows 10 file Explorer took ~2.5 seconds to open. Close it and re-open it: same thing. Open it, right mouse click another folder to open a new Explorer window: same thing. Fresh install of Windows 10 on a top of the line workstation-type laptop with 64gb of RAM.
Not all, but a frustratingly large proportion of modern software is dog shit slow.
The reason doesn’t need to spelled out in the article: if the developers of these slow apps cared, they could figure it out. From my experience, it usually looks something like this:
Some developer has an emotional attachment to Protocol Buffers, and will stop at nothing to see its adoption within the org. But their software is pretty heavily invested in JSON. So they rewrite the software to read the existing JSON files from disk (or REST web service response bodies, whatever), and reserialize them to protobuf in memory. Tada! Now we’re using protobufs, great. Of course, nothing meaningful was actually achieved here - they already had a perfectly fine, ready to use, deserialized, in-memory data structure before they added protobuf to the mix. Oh, and that plain struct in memory was faster than traversing a protobuf: the former had small substructures laid out in the same allocation as the parent, whereas substructures in protobuf involves multiple allocations and chasing pointers. Next step: realize that REST is lame, and gRPC is hip. But it’ll be practically impossible to rewrite everything from REST to gRPC, so they do the only reasonable thing: create proxies that sit between the client and server that translate REST requests/responses to/from gRPC! Now that we have that in place, we can add an additional proxy to the mix: Envoy. Envoy is a super popular layer 7 proxy, so it’s gotta be good. What functionality will be used? Any load balancing? RBAC policies? TLS termination? Nope. None of it. But because Envoy is “good”, adding it to the stack with no justification must also be intrinsically “good”, right? Right!
(Edit: do you see how long winded and boring this example is? This is precisely why the author shouldn’t expound on the “why” - anyone involved in the development of needlessly slow software (who isn’t blind to the problem because they are part of it) can recount similar craziness. Adding this to their blog would make for boring reading, and distract from the aim of their article.)
Buzzword/resume driven development, unwarranted layers of indirection (for no gain), absolution of responsibility via appeal to authority (if the top 10 software companies created and/or use some software, then surely we can blindly use that software too and enjoy the same success, despite not giving any consideration to whether it’s even remotely the right tool for the problem at hand), cargo culting, etc.
The reason software is painfully slow usually boils down to lack of critical, rational thought: either out of laziness and/or deferral of responsibility, or because of some emotional attachment to some type of software component.
This bloat is harder to deal with, on organization level, because people creating it justify it by saving on development effort necessary to make the product leaner. There's no financial incentive to not use Docker for deployment (and spend developer's time ensuring the code works on different platforms with different libraries).
And software industry isn't the only victim of this situation. First time I ever encountered this was in a... church. American missionaries coming to the former Soviet republics would bring with them pocket Bible for free handouts. Since I studied printing, to me this pocket Bible was strange in many ways. It was printed on paper lighter than 20 g/m^2. This was unheard of in Soviet printing industry. If it ever tried to produce such paper it would simply fall apart because they didn't have access to the technology necessary to produce plastics that held this paper together. Because the paper was too thin, it required a lot of "filler" (again, more plastic). And that made it worse for recycling. It was printed using offset machine. Soviet industry didn't print literature using offset machines. They didn't have the technology for making precise high-resolution plates necessary for such printing, so letterpress printing would be the way to do it. But, letterpress makes a noticeable difference in texture of the page, it also pretty much prevents you from using "unorthodox" font sizes, ensuring that the font's author could see exactly how letters are going to look on a page, making the overall experience much more pleasant.
All in all, it was kind of a technological marvel I knew I couldn't achieve with what I had / knew, on the other hand, all this technology was intended to decrease cost at the expense of marginal drops in quality. In truth, at the time, I didn't think this way. I saw the technological marvel part, and didn't notice the drops in quality. The realization came a lot later.
I'm suggesting that the blanket assertion doesn't hold true that slow software is painful software. Software can be so slow that it's painful but "slow" from the point of view of absolute does not immediately make something painful.
A counter-example that the author used when describing people with a pride in inefficiency was to quote:
> @tveastman: I have a Python program I run every day, it takes 1.5 seconds. I spent six hours re-writing it in rust, now it takes 0.06 seconds. That efficiency improvement means I'll make my time back in 41 years, 24 days :-)
I'm also asserting that slow and painful software that does what I want is better than fast software that doesn't or that I can't afford.
Heck, I empathize with the author: when I run Slack there is a perceptible delay when I type. Do I want them to fix it? I mean, no, not really. I'd personally rather they provide an offline search mechanism or a way to write direct CSS for theming. It's something that is annoying but it is less annoying that missing new features or the price going up. Likewise, I could use Vim for editing if I really wanted to, but I'd rather have the featureset of IntelliJ.
I agree with this. Though my interpretation of the blog post was that the complain was directed at the subset of "slow" software that is specifically "perceptibly slow, to a frustrating degree".
> A counter-example that the author used when describing people with a pride in inefficiency was to quote:
>> @tveastman: I have a Python program I run every day, it takes 1.5 seconds. I spent six hours re-writing it in rust, now it takes 0.06 seconds. That efficiency improvement means I'll make my time back in 41 years, 24 days :-)
Yeah, that quote (and attached commentary) did seem a bit out of place.
> I'm also asserting that slow and painful software that does what I want is better than fast software that doesn't or that I can't afford.
I agree here.
I suppose whether the blog post is is likely to resonate with someone comes down to one's prior notion of why frustratingly slow software is the way it is.
Some may believe that such software is developed by experienced, motivated developers who want to do their best work, but run up against a hard choice between allocating time to important features vs clever/tricky/novel optimization.
Others, like myself (based on my firsthand observations), believe that software can be just as feature complete while also being "fast enough (to not be frustrating)" all while using the same resources (dev time, money, etc). Developers just choose not to. It's not that anyone consciously thinks "hey, I think I'll go out of my way to write slow software" -- in the same way that (almost) no one thinks "hey, I'm going to strive to be morbidly obese"; rather, it's the lack of a conscious decision to employ self discipline and:
- Do not add layers of indirection because it "feels" right (I've seen countless changes that, upon questioning, can't be motivated beyond "I dunno, it 'felt' right"); instead, think through what you're doing. Just because you've thumbed through a design patterns book, or saw a blog post about dependency injection, or recently discovered runtime type reflection, doesn't give you license to cargo cult any of these things. If it was discovered that a bridge was constructed out of some material because the engineer(s) thought it "felt right", because the raw materials were "pretty" and "sparked joy", or maybe even "tasted good", I'm sure almost everyone would be horrified at such spectacular negligence. Somehow, similar behavior in the software world is perfectly acceptable.
- Do not add libraries and frameworks and orchestrators and pipelines because your ADHD compels you to play with new, shiny things. I have ADHD, and the compulsion is there, but I choose to ignore it.
- Do not use some tech just because it's popular, with zero critical thought, thus applying the wrong tool to the problem at hand. That's a recipe for slow software that requires more development time, as whatever time you save by not engaging your brain will almost certainly be eclipsed by the time wasted trying to contort the tool you're abusing.
- If you're about to spend the next hour working on something, first spend 5 seconds to see if the standard library has a ready-to-go, optimal solution to your problem. An example from firsthand experience: early in my career, I worked on a desktop GUI application, using Windows Presentation Foundation (WPF). One of our devs needed to add an underline to a text label. At our standup, he reported that he expected to spend the rest of the day working on that one change. He and the lead developer discussed how he could develop a new, custom control, and how the custom rendering routine would work, and gotchas to watch out for (naturally, you'd need to gather subtle font/layout metrics to know where / how wide to draw the underline), etc. I mentioned that an underline decoration is something that the standard WPF text label control already supports out-of-the-box -- the change would be something as simple as adding underline="true" to the respective XML element that declares that control. That was uncritically shot down with "No... no. I don't think that's a thing". The only reason we didn't lose 8 hours+ of developer time that day was because I did a 5 second Google search after that meeting, found the MSDN documentation page for that "underline" setting, and sent it to the developer, and he chose to implement that 5 second change instead of creating a custom component. Of course, the lead developer rejected the changes as "this wouldn't compile", though I had already compiled and spun up the app; because I'm diplomatic, I asked if he could look at something, and inquired "so, I know this underline probably isn't quite what we need, but I was curious if you could give some pointers on how our custom implementation would need to differ?" -- he was stunned, finally realized that the existing, bog standard control already had this functionality, and then approved the change.
I would bet anything that 99% of painfully slow software could be pretty snappy (or at least "snappy enough") if the developers thereof wouldn't create more work for themselves by doing inane things. No hyper optimization, bespoke algorithms, nor heavy R&D required.
What's so special in the modern software? How do you tell if software is modern?
Few points to illustrate the difficulties with your descriptions: BASIC and SQL were meant to empower people ... to write something "bad" a very long time ago. So did Fortran, as well as some other languages / technologies that didn't survive to the present day.
Python or Java can be called "conservative" if you are very generous, but, really, in truth, should be called "anachronistic" considering programming language development that happened in the 70. Languages like J or Prolog are conceptually a lot more advanced than Rust or Go, but have been created much earlier. Many languages are actually collections of languages that have been created over time, eg. C89 through C23 -- does this make C a modern language? Only the C23? Is there really that much of a difference between C89 and C23?
Is there some other way to define modernity? I.e. not based on time of creation nor based on some imaginary evolutionary tree?
Only in software, it’s fine if a program runs at 1% or even 0.01% of the possible performance. Everybody just seems to be ok with it.
So yeah, everybody is ok with it. Move on.
Surely you can see that this top list is optimized for features, not for speed. So yeah, people can complain here on HN all they want, in the end the 'evidence' of which software is preferred is pretty clear, even in the programmer demographic.
The truth is that a lot of conveniences we take for granted have a cost that adds up a lot. A 4K screen has 17 times more pixels than a 800x600 one, and uses 32 bit color. So the raw size of graphics made for a modern display is around 68 times bigger.
Where before a static picture was acceptable now the norm is a high quality, high framerate animation.
Arial Unicode is a 15 MB font, which wouldn't even fit in the memory of most computers that used to run Windows 95.
Spell checking everywhere is taken for granted now.
And so on, and so forth. That stuff adds up. But it makes computers a whole lot more pleasant to use. I don't miss 16 color video modes, or being unable to use two non-English languages at once without extremely annoying workarounds.
But animations for no reason other than to make it seem like waiting for something is less of a chore? Nope.
Unicode is something I’m willing to pay for.
But we should be able to draw the glyphs on the screen in single-digit ms like we did in 1981. Yes more pixels and more glyphs but it’s possible just not a priority.
In 1981 we drew fixed-width bitmap fonts at low resolution. In 2023, a font is a complex program that creates a vectorial shape, which is carefully adjusted to the display device it's being rendered on for optimal graphical results and antialiasing. That said, performance isn't bad at all.
Just resize the comment field back and forth while having a bunch of text within, and you'll see that text rendering performance is perfectly fine. I see no slowness.
This comment is something like even after paying 100K for performance BMW car engineer tells the user car will take 30 sec for 0-60 mph. And since user is not perf expert they have to take it face value.
It's not?
Software used to be way, way slower. I had a 386. I experienced things like seeing the screen redraw, from top to bottom in games running at the amazing quality of 320x200x8 bits. I've waited hours for a kernel build. I've waited many seconds for a floppy drive to go chunk-kachunk while saving a couple pages of Word document. I've waited minutes for a webpage to download. I remember the times when file indexing completely tanked framerates.
Today all of that is pretty much instant.
Then as the team grew, the values changed to favor anything that improved developer efficiency. More abstractions, more layers, more frameworks. The tradeoff of saving one day of developer work was worth the cost of millions of user seconds collectively. I think the difference was just the visibility - management can see the costs of things on the development side, but they can't see the benefits of a slightly faster launch time, or better caching, or smoother scrolling. They aren't measurable, and once an org gets to the point where all it cares about are measurable numbers, I think this is a natural course.
Of course, that's until AI gets to the point where it can fix everything we (or it) programmed wrong, including AI itself which is highly inefficient just like the OP predicts.
It also over-prioritizes readability if anything, using descriptive variable names and documenting every line with a comment. It's maybe not as good as the best engineers at considering all these factors, but I'd say it's better than the average developer, and may be better than the best engineer too when that engineer is tired and in a hurry.
Cars were optimised only after external (oil) shocks were applied, and even then very unevenly (American cars continue to be very inefficient). In fact, inefficient products are often more profitable in practice, as customers have to replace them more often; the crappy iPhone cable that splits after a year means Apple can charge you again (and again) for its replacement. White goods now break more often, but they're built more cheaply so they can make per-unit profit higher than it would otherwise be. What matters is efficiency producing, not after-sale use.
Capitalism in software means churning out new automation as quickly as possible, letting consumers pick up the resulting waste of energy and time. The production chain gets more and more standardized and optimized: you can now swap React developers, or Kubernetes admins, like you can swap warehouse workers, with all that it entails in terms of salary pressure. Some of that automation is effectively self-justifying, in the same way accountants make accountancy terms obscure so they can justify their jobs; but that's about it. Everything else is about profit.
A lot of engineers forget that they are in fact paid to build a product for customers.
edit: It also seems OP has never had to wait for older Windows or Linux machines to fully boot. Modern versions boot much faster because customers wanted that. Phones are on 24/7 so customers don't care if it takes longer to boot once every few months.
My Commodore 64 from the early 80s booted to a full BASIC REPL in around 1 second. Yes, loading from removable media was slow, but the computer was ready to fully use in less time than it takes "modern" systems to even POST. Totally ridiculous.
My BIOS takes like 20 seconds to POST, and that's apparently normal. (then ~10 seconds for the OS to boot)
By your logic Tesla and Apple shouldn't have grown like they did since customers wouldn't pick them over existing incumbents. Customers do have a choice in aggregate and they express that choice. Some people who don't agree with that choice try to say customer's have no choice but in the end they do and the person saying it is upset they're a minority.
They have enough power to shape the landscape itself, and as such they can drastically steer the outcome of "customer needs"
Neither of them used to be the giants they are but overall they made solutions that their customers (who are, btw, advertisers in Google's case) wanted and bought over larger existing competitors. Apple's market cap has increased 500x since the late 90s.
Obviously they entered the market with simply good products, but that doesn't change the fact that now they have a lot of power that comes simply from their size. Im not saying its their only advantage, just that it plays big role.
But also, common now. Today's platform lockins are much more impactful then anything we had in the 90'. And you don't compete with Google's product anymore, but rather you compete with ecosystem that half of the world bought in. Which makes it practically impossible to be a viable alternative
In a way yes but I think in many ways software became much more than that. In many ways it became a crucial part of human lives as electricity or medical services. And you can say doctors/engineers are being paid to develop new medicine or a new power sources but these have many many levels of government control just because how sensitive and important the matter is, which is not the case with software (yet?).
A few previous discussions about this blog post:
https://news.ycombinator.com/item?id=18012334 (Sep 2018)
It's important to remember that as developers, we do have a choice. Not about everything, but there's an option to choose the less-sucky alternative.
You don't have to use Node. You can write good, backwards compatible software just fine on the .net or JVM ecosystems and you can know that it will still run without modification in 10 years.
You don't have to write single page webpages. Old-fashioned HTML that completely reloads the page on each click works just fine and is probably lower latency at this point.
You don't have to write desktop apps using Chromium. Getting started with a UI framework is a little more work but the quality is worth it.
The decision isn't always yours. But when it is, opt out of the suck.
(Cough)
The .net core initiative broke A LOT of code. Microsoft obsoleted a lot of libraries. (Some for very good reasons, too. A lot of legacy .net libraries had rather poor design choices.)
Industry prioritizes functional solutions (requirements) over efficiency. If efficiency is one of the requirements, it will be addressed (e.g. video games). Optimizing for efficiency takes additional effort. The article argues that the software industry is stuck with inefficient tools and practices. Engineers can and should do better, aiming for better apps, delivered faster and more reliably with fewer resources. However, economy dictates that as you optimize two variables from the triad, the third will get de-prioritized.
Edit: I can see the downvotes but no idea why. Would you care to explain?
I dunno, but this has been taught in PM since PM. I remember learning it in the 90s and it still holds true. If you want it fast and a large scope, you have to throw bodies and planning at it, costing money. If you want it cheap with a big scope, you have to wait for that small team to finish it (time). If you want it fast and cheap, you have to limit your scope.
Time/Cost/Scope, pick 2. Perhaps people are taking issue with quality vs scope, but quality is a part of scope for certain.
https://www.projectmanager.com/blog/triple-constraint-projec...
Isn’t that what drives the most sales in upgrading a phone? Idk many people that care about the microscopic improvements to the camera or UI, most of the time it’s something along the lines of “my iPhone 8 doesn’t run fast enough anymore, time to upgrade”. Same with consoles. I remember one of the big pitches of next gen consoles being “look! No more loading screens!”. And even ChatGPT 3.5 vs ChatGPT 4. There are tons of people that will use crappier output because it’s faster. Speed is still absolutely a selling point, and people do care.
Those are the very specific use case I mentioned.
How many users are gonna swap to a different chat client because of this or a different word processor because it start 1s faster? As a parallel comment points out, even developers swapped away from the very quick Sublime to Atom and now VSCode. At work hiring at some point became a huge pain because we swapped from Greenhouse to the recruiting tools built into Workday. It was super slow. I hated it, our recruiting team hated it, but it was purchased because it checked all the boxes and integrated with all our other stuff in Workday. The comparison to engine efficiency made me think that if we really want faster software, we need the equivalent of a gasoline tax for software, but what's the negative externality we are preventing?
That suggests that while those three factors are part of the explanation they’re not sufficient to explain it alone. My theory would be that we’re imbalanced by the massive ad-tech industry and many companies are optimizing for ad revenue and/or data collection over other factors such as user satisfaction, especially with the effects of consolidation reducing market corrective pressure.
It's a tragedy of the commons, where everybody would benefit from better tooling, everybody wastes time dealing with poor tools, but nobody is willing to put time/effort/money into making better tooling.
There's plenty of FOSS developers that work for intrinsic rewards and likely produce better software.
Like at my last job, we had something like 50 microservices, Kafka, rabbit, redis, varnish caching, etc. For under 1k external requests/second and some batch processes that ran for a few million accounts. If we cut out all of the architecture to "scale", you could've run the whole thing on a laptop if not a raspberry pi. And then a real server could scale that 100x.
The company was looking at moving to a "cloud native" serverless architecture when I left.
The impossible trinity (also known as the impossible trilemma or the Unholy Trinity) is a concept in international economics and international political economy which states that it is impossible to have all three of the following at the same time:
- a fixed foreign exchange rate
- free capital movement (absence of capital controls)
- an independent monetary policyThough times are changing in that world too. Sometimes you have to use a library. And more and more those libraries require an RTOS. Just about to make the plunge into Zephyr so I can use the current Nordic BLE SDK.
Having hard limits to RAM and flash is a great way to prevent bloat. Management is happy to let engineers grind for a month reducing code size of it means the code will fit into a cheaper MCU with less flash and save a 10¢ on the BOM. Pure software has no such incentive to minimize resources because the user buys the HW separately. If anything, some SW companies have an incentive to add bloat if they're the same company that sells you a new phone when your old one becomes too slow.
We used to have a social contract between industry, academia and society. Company invents widget, it pays into a university's endowment, student goes on to start the next company.
Today that's all gone. Now company invents widget, billionaire keeps the money, student gets forgotten as university is defunded and discredited through various forms of regulatory capture. Often to thunderous applause.
The stagnation of tech and the subjugation of the best and brightest under the yoke go hand in hand. Your disempowerment is a reflection of how far society has fallen. Loosely that means that even though we know how to make programming better, we will never get the opportunity to do so, because we'll likely spend the rest of our lives making rent. Which is the central battle that humanity has faced for 10,000 years. Like the tragedy of the commons, we work so hard as individuals that we fail at systems-level solutions.
Programming won't get fixed until we stop idolizing the rich and powerful, and get back to the real work of doing whatever it takes to get to, say, UBI.
In physical engineering, if a mistake is made, the bridge collapses, lives are lost, and therefore there is a deterrent against mistakes. But in software/movies, nobody cares if there are 10 flop movies/software, as long as one works/pays off.
This isn’t to say Apple doesn’t have their own problems but I think it’s not an accident given that Google’s focus is on showing ads while Apple’s is maximizing device value, minimizing energy usage, etc.
The web is frustrating because it’s so easy to hit high frame rates at low power usage in a modern browser, but everyone internalized that “move fast” BS focused entirely on developer experience and half the industry consolidated on a slow framework from the IE6 era rather than learning web standards. It makes me wish browsers had an energy-usage gauge so you’d have to own that decision publicly similar to a fast food place having to list calories in the menu.
I think software companies should just be more comfortable with rewriting code.
Sometimes you have to do it because your requirements changed or assumptions proven incorrect.
Move fast and rewrite things.
Consider: people complain a lot about Electron app bloat. Why can't Slack optimize a bit? Well, they have a lot of Mac users. One obvious way to optimize would be to incrementally port the most performance sensitive parts of their app to use AppKit so Apple's highly hardware-optimized UI toolkit handles those parts, and Electron handles the rest.
Problem: doesn't work. You can't embed an NSView into a Chrome renderer. This was once possible using the Netscape plugin API, but it was removed many moons ago and now you have to use HTML for everything. Electron is popular, plugins were popular, and Chrome could add these capabilities back and even do them better, but they don't because if your app is pure HTML then this maximally empowers the Chrome team. They can do lots of stuff to your app, and add value in various ways, and if the price of this is less efficiency or that some features become less consistent or even harder to implement then this is a sacrifice they are willing to make.
The result is that a lot of these discussions go circular and just become moanfests, because the ideological constraints of the platforms are taken as unarticulated givens: immovable objects that are practically laws of nature rather than things that can be changed.
There is no specific technical reason why you can't have apps that start out as web apps but incrementally become native Mac or Windows apps as user demand justifies it, it's just not how we do things around here.
The hard part isn't native embedding web, it's that if you start with web you then can't easily stick a native view into e.g. an iframe.
Can Electron not "tree-shake" parts of the browser engine that are unused? Either by static analysis or manual configuration? Seems like a real missed opportunity to trim down on bloat...
According to Google, a Chromium build on normal hardware takes 6+ hours.
And alas, even if it was feasible to custom build based on what you need, it would have to be done via configuration--since there's no way to know at compile time which language features will be used, since your app could (and probably does) include remote scripts.
Yeah that sounds about right - I use a chromium on Android fork and according to the lead developer, it takes about 3 hours for a release to compile and that is after optimizing the process as much as possible.
And in the web browser, I believe v8 is using snapshots of the js runtime to avoid much of the work of initializing the js side of things: it just forks a new copy of itself.
This is one of the prime strengths of alternatives like Tauri, that use a shared library model rather than having a static library. With Electron you have a ton of initialization to do for a very excellent runtime, but then you never get to reap that existing work again. Where-as on the web, we open new pages and tabs all the time, and avoid the slow first load & get to enjoy the very fast latter instance loads. That multi-machine capable vm pays off! With Tauri, the shared library may well already be in memory and initialized. Only the first consumer of the shared library has to pay the price.
From what I could tell of the config files, Chromium is pretty modular. It looks like you could just delete a few lines and have it avoid compiling entire subsystems. But I didn’t ultimately achieve my goal because I couldn’t get it to compile with those changes. IIRC it hit a linker error and I couldn’t figure out what to prune next, and I wanted to get back to actually building my product. (I ended up switching to Tauri anyway)
Part of me wants to revisit that project though. It would be so great if there were custom minimal builds of Chromium for Electron apps.
The main reason for this is politics. The Chrome team is ideologically wedded to the idea that everything should be a web app running on Chrome. They see desktop and mobile apps as the "enemy" to be wiped out by making the web do more and more stuff, until Chrome is the universal OS. Classical ChromeOS is the pinnacle of this vision - a computer that only runs a web browser and nothing else.
Chrome's architecture reflects this, um, purity of vision. It is not reusable in any way and the Chrome team do not care to make that easier. Projects that make it embeddable or reusable are all third party forks that have to maintain expensive patch sets: CEF, Electron, etc, all pay high maintenance costs because they have to extensively patch the Chrome codebase to make it usable in non-Chrome apps. The patches are often not accepted upstream.
This problem also affects V8. Several projects that were originally using V8 are trying to migrate to JavaScriptCore or other JS engines because V8 doesn't have a stable API and building it is extremely painful. It's a subsystem of Chrome, so you have to build Chrome to get V8.
This is a pity. There's a ton of great code in the Chrome codebase, and it can be built in a modular way (with millions of small DLLs). It's slower to start up when you do that due to the dynamic linking overhead, but it does work. Unfortunately for as long as the Chrome guys see native apps as a bug to be fixed and not a reality to be embraced, we will continue to have dozens of apps on our laptops which statically link an Xbox 360 gamepad controller.
There are a few possible solutions for this.
One is to not write Electron apps. Java went through a modularization process in version 9 and since then you can bundle much smaller subsets of the platform with your app. I guess other platforms have something similar. Obviously, native apps also don't have this issue both because the platform comes with the hardware you buy and because they tend to be more modular to begin with. But, people like writing Electron apps because it gives you the benefits of web development without many of the downsides (like the ultra-aggressive sandboxing). The nature of the web platform is that it always lags what the hardware can actually do by many years due to the huge costs of sandboxing everything so thoroughly, whereas Electron apps can just call into native modules and do whatever they need, but you can still use your existing HTML/JS skills.
Another would be for an alternative to Electron to arise. There are experiments in using system WebViews for this. That doesn't make the web platform more modular, but at least means it's a single install is being reused. You could also imagine a fork of the web platform designed for modularity, for example, in which renderer features are compiled out if you don't need them or even bringing back renderer plugins.
Another is to just tackle the issue from an entirely different angle, for example, by opportunistically reusing and merging Electron files on disk and in memory between different apps. If you ship your Electron app to Windows users using Conveyor [1] (or in the Windows Store using MSIX) then this actually happens. Windows will reuse disk blocks during the install rather than download them, and if two apps are using the same build of Electron the files will be hard-linked together so only one copy will be in memory at once at runtime.
But fundamentally the issue here is one of philosophy. Chrome wants to rule the world and has a budget to match, yet their approach to platform design just does not scale. For as long as that is the case there will be lots of complaining about bloat.
[1] https://hydraulic.dev/ (disclosure: my company)
I'm not surprised, and doubt the Firefox team is any different in that regard.
So far at least the Chrome team hasn't removed from Chrome the ability to go to a new web page in response to code external to Chrome, so we have that to be thankful for at least. Yay?
(The desktop code I maintain achieves that effect by invoking /opt/google/chrome/google-chrome with the desired URL as an argument.)
And yet, full disclosure and admitting to cognitive dissonance, for a (hobbyist) C++ game engine I'm currently working on that targets Emscripten for a web build and native for Debug build, I'm considering not even having a native-Release build at all.
The idea being if it's web-first and the native build being only for developer use for debugging, I could do things like supporting only one desktop graphics API (e.g. just DirectX) and optimizing the native graphics pipeline for simplicity over performance. End users would/could just use the web version.
Granted this is a bit different because I wouldn't be distributing a browser too a la Electron; it would just use the browser the end user already has. Just thought it's interesting that it's easy for me to criticize others, but with the choice of how to spend my own limited developer time (my free time) it's looking like this way of doing it makes the most sense.
But if something is proprietary and cloud linked anyway I would much rather it all go through the web. That way open platforms still have a chance.
If banking apps and and Google payments and proprietary IoT devices controllers were all on the web, then a Linux phone might actually be viable!
I'm guessing eventually the native free software would move more and more into the browser too, but that's fine as long as you can still run the stuff that hasn't been moved yet or isn't interested in moving.
For many years I worked on my own game engine which combined a C++ core with an interpreted scripting language. I had developed a system of language bindings which allowed the interpreted language portion to call functions from C++. The engine quickly grew to a multiple-gigabyte executable (in the debug build), and no matter how much I tried to optimize the size it was still unconscionably huge.
One of the reasons I eventually gave up on the project was I realized I was overlooking a simple mathematical truth. The size was NxM, where N is the number of bindings and M the size of each binding. I was focusing on optimizing M, the size each binding added to the executable, while not just ignoring N but actually increasing it every time I added bindings for a new library I wanted to call from the game engine.
There were diminishing returns to how much I could improve M because I was relying on compiler implementations of certain things I was doing (and I was using then-new next generation C++ features that weren't well optimized); it would be a lot easier to simply reduce N. And the easiest way to do that would be some sort of tree shaking.
Unfortunately due to the nature of interpreted code it isn't known at compile time which things will/will not be ultimately called. That determination is a runtime thing, by calls via function pointer, by interpretation of scripts that start out as strings at compile time (or even strings entered by the user during runtime).
From a compile time perspective, static usage of every bound function, feature or library already exists - it is the C++ side of the cross-language binding. That's enough to convince the linker to keep it and not discard it.
In fact, the mere presence of the bindings caused my game executable to grow more per each included library than would a similar C++ -only, all-statically linked program. If a library provided 5 overloads of a function to do a similar thing with different arguments, an all- C or C++ application that uses only one of them would need only include that version in the compiled executable; the others would be stripped out during the linking step.
Since I don't necessarily know ahead of time which overload(s) I'm going to end up using from the interpreted language side of the engine, I would end up binding all 5. Then my executable grew simply from adding the capability to use the library, whether or not I make use of it, but moreover if I did use it my executable grew even more than an equivalent C/C++ - only user of the library because I also incur costs for all the unused overloads.
You can see why something like Electron would have the same problem. Unused functions can't be automatically stripped out because that information isn't known at compile time. To do it by static analysis the developer of the Electron app would have to re-run the entire build from source process of the Electron executable to combine that with static analysis of the app's Javascript to inform the linker what can be stripped out of the final executable.
And it bears mentioning neither such a static analysis tool for Electron app Javascript nor the compiler/linker integrations for it currently exist. In theory they could exist but would still have trouble with things like eval'd code.
Manual configuration would be possible but necessarily either coarse-grained or too tedious to expect most developers (of Electron itself or users of Electron) to go into that much detail. That is, you may have manual configuration to include or not include Xbox 360 controller, but probably not for "only uses the motion controls" while not including other controller features.
Either way you wouldn't be able to add-back support for it Javascript written after build time turned out to actually need the function or feature after all, unless you distributed a new executable. If you're building so much from source with configuration and static analysis, at that point why not write your whole application in a statically compiled language in the first place?
My thesis here is not that we should accept things like Electron being bloated because they cannot be any other way. My point is (as happens time and again in Computer Science) we had certain things already (like tree shaking and unused symbol stripping during the linking stage of statically compiled languages) and then in the name of "progress" let them either be Jedi-mind-tricked away or the people developing the new thing didn't understand what was being left behind.
Yeah, but I'll bet those car designers didn't close the requisite number of story points in their sprint! So really, who's laughing now?
So, I play the original one in DOSBox-x. Maybe it is nostalgia, but I love vibrant pixels and the Sound Blaster music.
The key here is "I run every day" - if you're only saving CPU for yourself once a day then, well, fine. But if the improvement is about something that runs millions of times a day, or is run once a day by a million people, then that's something completely different!
Y'know why software sucks? People. People are hard to manage, hard to incentivize, hard to compensate. Focusing on the slow loading web page is neglecting the economic incentives to bloat the bundle with trackers, to ignore perf work in favor of features, to not compensate open source developers.
The point about engineers in other domains doing it better, well I'm not exactly convinced about that (look at the bloated cost of building in America). But taken as true, they're doing better because there are economic, legal, and social incentives to do better. Not because they're just better at engineering.
If you're making a building or a bridge, it may have some aesthetic or small functional qualities that make it unique, but 99% of the job is to make it with the same success criteria as every other building or bridge. The building needs to stand up, hold people, have X amount of floors, and not fall over. A bridge has to get people/vehicles over it and not crumble.
Pretty much every piece of software is expected to do something new and innovative. It starts off with an abstract idea and details are filling in as you go. You stumble into some roadblock because of some design conflict that wasn't obvious until you were implementing. If the software is being made at the request of a client or your company, they probably gave a bunch of success criteria that has a bunch of inherently contradictory ideas that they'll need to compromise on because users don't actually know what they want until they're using it. You finish off the first version, they identify all the things that aren't working, and now there's new success criteria you need to implement built off a foundation that wasn't prepared for it. No architect ever finished erecting a skyscraper only to be told it needs a major change that will involve reworking all the plumbing.
That's the inherent difference. Software is a game of constantly trying to chase a moving target, and most of it is being built on a stack that is trying to chase moving targets at every level.
I loathe building new features, adding new functionality, starting yet another product launch, etc. Yet it feels like 80% of my time at my job is doing the above, probably more.
nobody will complain if your software is faster, or simpler, or just plain better. And I can happily spend the remaining years of my career making that happen.
Software developers need to quit building yet another front end framework, and get back to the actual engineering aspects of making things more performant. IMO, it’s far more rewarding.
The number of times I've seen an endless spinner or a button that doesn't work.
Getting people to use (and improve) "your way" of doing things is difficult. (Web frameworks and javascript frameworks)
Programming for me was always about connecting to a machine. I started writing games and native desktop applications in C/C++.
My first job was for a dot-com start-up that was a bit ahead of its time. Basically it made web-based office productivity software before we had terms like "the cloud", when Google was just getting off the ground and there was no GMail or Google Docs etc. That was how I got started in web application development and for many years it was grand. I was a "full stack" developer before "frontend" and "backend" were concepts. We needed to know how to optimize our SQL queries, avoid SQL injection vulnerabilities, and we even developed our own dynamic templating language using C++.
We offered a "hosted" version of our product but also a "self-hosted." Bare metal servers were the thing. We needed to be able to port our software to multiple operating systems and have it run on all sorts of hardware.
One of the most significant differences in the customer relationship was that if we wanted more business from our customers, we needed to convince them that upgrading to the newest version would be worth their time and money.
These days everything is SaaS, "cloud" and CI. As a user I need a fucking user account for every single piece of software I want to use. All of my data is hosted on someone else's computer which isn't even a computer. It's some virtual data centre hosted inside of an AWS data centre. The product owners of the company will use me as a perpetual beta tester, throwing any shit at the wall that they can think of hoping something will stick. The products constantly degrade in terms of performance and UX and I have no say other than to stop using computers and software all together.
Which is starting to happen.
I'm a software engineer that avoids using software in my personal life as much as I possibly can.
I think correctness is often much more important than efficiency, elegance and other things that can sound like conceits or misalignments.
I don't mean some academic or niche formal proofs notion of correctness. I mean ordinary everyday minimal level of competence of systems. This includes that the system exists in the actual real-world environment of normal users, as well as the actual real-world environment of attackers. We often fall flat on both aspects.
It's one of the biggest problems in software. On average, our field behaves like criminally irresponsible, incompetent clowns, who casually pull prop clown horns out of our posteriors (and StackOverflow and ChatGPT), commit them as part of our sprints, and call it done. And frequent "security updates" and "bug fixes" for what should be considered irresponsible failures needing deeper corrective action.
Personally, I'm considering next working on things that have a high priority to work correctly. Which by default is humbling, but it becomes downright scary, when you consider that very little of the software, infrastructure, and personnel ecosystem on which we depend has been developed with a sufficiently responsible and competent mindset.
Even open source suffers from the same problem. Making really high quality software takes 10 times the effort (if not more) and nobody is willing to make that investment up front. And so half-baked software becomes popular and now we spend years or decades and untold hours trying to turn bad software into pretty good software without completely breaking backwards compatibility.
The root cause is probably the incrementalist approach we take to developing software. We start with something small because of time constraints or because we don't really understand the problem yet. Once the software has users who demand bug fixes and feature additions and this results in software organically growing instead of being intelligently designed for a purpose. As a result, you get stuck in a local maximum.
And that's how we spend 500,000 hours debating strategies for removing the GIL (global interpreter lock) in Python when the first version of Python was made 30 years ago as a side project during a holiday break.
I would blame the "unix philosophy" and "worse is better" approaches of the past, but I bet they were more symptomatic than causal, and their equivalents in other digital realms pop up all the time: IBM vs clones, unix wars, protocol wars, at various times its fights between 'official' (described as stuffy) vs 'pragmatic' (described as lax/crappy) definitions of stuff.
I'd hazard a guess that since (for those of us who are young and therefore spew confident sounding incorrect speculation like this comment) we still have so much of the old 'it works, ship it' hacker groups of the 70s in our past, then the overreach of the CASE / UML / XML fever of the late 90s which we have in turn overreacted against by going too far in the 'look its a containerized k8s pod running behind a reverse proxy that runs some react and uses leftpad to graphql your (must always be online) user information record in this headless electron because SHIP IT' direction.
PS: our historical 'its good enough' precedent didn't help, we've been trapped on 'very fast PDP-11s' for decades. Even BWK and the other forerunners of our modern C + unixlike stack weren't able to get us un-stuck from that stack and so plan 9 etc. failed to catch on. The Lindy Effect is a double-edged sword for sure.
I feel like every application I purchase or download or try to setup is unsatisfying and flawed in some way. I paid $30/mo for access to the EastWest Composer cloud and was excited because I had spent most of my music production career hearing people talk about this near-infinite library of amazing sounds that professional producers use and I was about to have access to it. Then I downloaded their plugin and it was dreadful. Crashed regularly, I never actually got it fully working even after working with support for a month or so.
It feels like everything is like that now adays. Most pieces of software that I use I just immediately learn to smooth over the errors in one way or another. A reboot before creating each new project, etc.
It even works into a lot of hardware things because they need software too. I paid $500+ for a gopro MAX and the GoPro app has been the biggest nightmare in trying to use that device. Plus the firmware is dreadful and the wifi tech they use to connect is clunky.
It depresses me too. I feel like I can't even spend money to find a solution anymore and it feels like I end up throwing my money away more often than not because I buy something and it's clunky and awful but I can make it work so I use it sometimes but I could be getting so much more for that money if they had spent time refining the software.
It seems to me as if GoPro is basically a shell company consisting of a lot of marketing people and MBAs without technical understanding beyond using iPhones just contracting tech work out to off-shore.
The experience was better when I tried downloading Insta360's 360 video editor! Still not sure what to do with the 360 camera anymore lol but that's my own problem not gopro's.
Which of course would be good, if that's what the stack does. But the stack doesn't do that. The stack constantly introduces new, crappy abstractions that eventually no one wants to use directly anymore, and people build new ones on top. Eventually, the new ones on top start to resemble the ones below, until we end up with a cycle. This mislayering is known as "abstraction inversion"--the abstractions at the top end up being crappy and slow reinventions of abstractions deeper in the stack.
It won't ever stop because people keep fancying themselves the most awesomest library designers ever and keep coming up with new crappy ways that clearly not everyone likes. It's an endless game of promising the world but delivering a spray-paint job over someone else's world.
... $ time emacs -Q -eval '(kill-emacs)'
Takes 86 milliseconds I think. That's launching graphical Emacs on a 4K display (well nearly: 3840x1600) ("-nw" / "no window" would be even faster), running elisp code, and exiting back to the terminal.
I'm running the very small "Awesome WM" tiling WM with 12 virtual workspaces and switching between them is ultra snappy.
Now, sure, countless websites using way too much unnecessary monothreaded JavaScript and calling way too many microservices have insufferable network and redraw latency (even though I've got a fat and low-latency fiber pipe to the home), but my computer is still incredibly snappy.
My Ryzen 7000 series CPU is so quick I actually set it to always be in "eco mode" (in the BIOS/UEFI) and don't bother to run it at its max speed.
I'd say hardware is amazing compared to what we had in the past and software, if you're careful, can be very snappy.
That thing will reach months of uptime if I want: not just the OS but the software as well. I'll reboot for critical security updates mandating a reboot (extremely rare) and when I go on vacation but that's about it.
I know, I know, I should turn it off: but the thing is so stable I don't even bother. At night I switch to a virtual workspace that puts the CPU in "powersave" mode (actually of my 12 virtual workspaces, only the one where I "dev" turns the CPU to performance mode and as soon as I switch to another workspace, I put the CPU back to powersave: hence broken JavaScript pages won't make my fans runs loud).
Needless to say I was primed for this article and it is a thoughtful and apt read.
The biggest gut punch of it all is that this article is _from 2018_.
As I get older (I'm 38), embracing as much dumb hardware as I can. I smarted up our house with HomePods and Siri started not recognizing the sound of my voice. JFC.
And, the fact that software can be continuously updated in the field makes it inherently different than other fields, which have to try to get something “right” the first time.
But I also think that we have a responsibility as engineers not to thrust technology out into the world without considering its impact, and that includes things like Electron. At its inception, I'm sure it was a hilarious and insane tech demo, but that's all it ever should have been.
The sad fact is that Electron solves a real problem, though, which is that developing per-platform native apps takes an enormous amount of effort. To me, it's a huge failing of the software world that we've not yet provided an alternative that's just as easy to deploy as Electron, if not easier, but with performance and efficiency built in from the start.
That's not the only reason, although it is one. Two of the other big reasons for this are:
1. The content is often loaded async while the boxes render, and this hides the latency of doing a network fetch.
2. Animating text looks terrible. Even if you had a perfectly fast computer, you wouldn't want to animate boxes filled with text and images, because it looks really bad.
There's a cost to waiting for a feature to be done your ideal way to your ideal standards - that's the cost of all the people not being able to use it while you add perfection. It's money left on the table but also just efficiency in the world economy that's being delayed.
Programs were not that great in C or C++ in terms of being able to run for a long time. I fought the once-every-2-week crash bug in a C++ program - a single double memory free under certain uncommon conditions. Finding problems like that was very very unproductive.
Cars, to give an example, are often made with space for all the possible optional bits even when that model will never have them - because it's more cost efficient to have a common design among several models than to redesign each one.
Of course "progressing in reverse" is the same thing as saying we're regressing.
The hardware guys are working away to make hardware better all the time - whatever software people are doing. We could tell them to stop doing that, get other jobs so we could just write more efficient software . . . . but why?
When they run out of things to do we will be forced to concentrate on using what we have more effectively. Before then however, the most stupid thing to do would be to leave that capability they're providing unused.
as an example; I use MS Teams a lot - it's horrendous and ridiculously inefficient and I would love to have some stern words with the development team. OTOH I get lots of use out of it. It may not be the best of it's kind but it's what my company chose and it does a lot of very useful things. Better to have it than not on the whole.
Let’s keep the standard for performance high and continue to highlight performance issues.
You can still get software quality but you have to be willing to devote time and effort to it. The binary for my modern, commercial background job engine written in Go, Faktory, is 5MB in size.
https://github.com/contribsys/faktory/releases/tag/v1.8.0
I know when I see an iOS app that is 5-10MB in size, I know it was crafted by someone who cares. Overcast being one example.
It's hard to complain when everything is so cheap and easy. 40 years ago we might have literally written letters for everyday utilitarian purposes. Even if you added a limit of 2 characters per second that you could type, I'd probably get used to it and say "Still faster and easier than a pen".
And on top of that, stuff seems to get faster all the time. The new Ubuntu no doubt is packed with more code than ever... But it feels faster than Kubuntu. I assume they fixed some big in allocating resources or something.
Every generation of software is more secure even if less private, subjectively I notice more reliability every year.
These days we have watchdogs to restart broken apps. Maybe every day it's down for a minute. Back then, people didn't always add that, they just "Tried to get the code right"... And it would be fine for a year and then be down for hours.
Modern software is more predictable. Overall quality might be less, it might crash weekly instead of monthly, but a reboot is far more likely to fix it, we have fewer places were your app writes a bad setting and now it never opens again till you manually edit something.
We can always do better. We very much should. But I'm generally happy with the current state.of software, and most consumers seem to be too.
High complexity, ugly / unplanned, high rent (cloud costs, etc.), bloated, only polished on the surface, and designed to gather as much market share as possible as fast as possible and we'll fix it "later."
Examples: Electron, Kubernetes, Helm, expensive managed cloud, lots of domain specific languages and other high cognitive load systems demanding high staffing requirements, total abandonment of labor saving tech like WYSIWYG design, etc.
If a major automobile manufacturer is able to get away with still using its 50 year old engine block design based off of valve technology that's a century old at this point, and crowbar it into everything from pickup trucks to supercars with success, I can guarantee you that it's not operating at the cutting edge of material and thermal engineering.
> Would you buy a car if it eats 100 liters per 100 kilometers? How about 1000 liters? With computers, we do that all the time.
A more apt analogy would be, "would I buy a car that gets 100,000 km/liter over a nicer car that gets 1,000 km/liter?".
Seeing as a I drive about 12k km/yr, the difference in cost in absolute terms is negligible for me (it would be about a $25 Euro difference), even if it's a huge improvement percentagewise. Sure, there's no cars that get this kind of performance, but for computers, the cost of running my laptop for an entire year is less than what an hour of my work-time is worth. If energy were 10 times the price, it would still be negligible.
Just look at the quoted example:
> I have a Python program I run every day, it takes 1.5 seconds. I spent six hours re-writing it in rust, now it takes 0.06 seconds. That efficiency improvement means I'll make my time back in 41 years, 24 days :-)
So this person took six hours to write code that saves 1.44 seconds/day. So it will take 15,000 days to make back that time (I know, I know... they probably did it for some intellectual satisfaction rather than to actually save time).
But as I said, I still agree with the sentiment of the article. There are so many cases where making code more performant wouldn't even mean a significant amount more work... it would just mean watching out for very heavy libraries, doing some negligible performance tweeks, etc.
I agree with the author's call to action though:
"As engineers, we can, and should, and will do better. We can have better tools, we can build better apps, faster, more predictable, more reliable, using fewer resources (orders of magnitude fewer!). We need to understand deeply what we are doing and why. We need to deliver: reliably, predictably, with topmost quality. We can—and should–take pride in our work. Not"
Not if we have project managers we can't.
The problem is there are engineers who will take your paycheck and build crappier software more quickly, because there's barely any quality regulation for software. That's the difference between software and other traditional engineering disciplines. An electrical engineer has their license at stake.
You’ll usually pay them better than the engineer who delivers a better quality product in more time.
Every divorce starts with a marriage. Any delay starts with a planning.
I've been programming for over 40 years. OP's take is a classic underestimate of how many features new versions of software have added.
My first computers in order had:
64k of RAM
128k of RAM
640k of RAM
Those first two booted up literally instantly as they copied firmware into RAM. That last one booted up in about 10 seconds from an unbelievably slow C: drive.
What did all three have in common? Did not even have basic networking built-in. Yes, systems are bloated today but they do so much more than the systems you're comparing them to. Yes, they could re-write them from scratch to remove this bloat but we knew for 8 years before OP started coding that is not the right answer either.
https://www.joelonsoftware.com/2000/04/06/things-you-should-...
1) Product managers have more influence and decision making in prioritizing what should be delivered. I have routinely encountered wherever I worked that any work related to improving efficiency or spending time in non-business related work is constantly de-prioritized. Controlling programmers time means certain system bugs get lower priority and junk accumulates over time and software gets bloated. There are code-path ways which are not being used anymore but no-one bothered to clean up as they have not been instructed to do so yet.
2) I find the explosion of javascript in popularity is a major reason of this inefficiency. Imagine the compute and electricity wasted globally because certain developers don't want to build multi-threaded applications and prefer dynamic typing.
Oftentimes it is make or break for a company/project to get the programmers to follow yagni. Cleaning up old code can very much offer no value (short or long term) to the product, the conpany or the user. And a programmer who is zoning on a task or story should not need to pull himself out of that.
My expertise was centered around data management; particularly file systems. So when hard drives got big enough to hold more than 100 million files; I realized that the decades-old file system architectures could no longer handle them efficiently enough for my taste. So I set out to build a better type of file system (a data object store).
I spent weeks (sometimes months) fine tuning algorithms and code paths to make it as efficient as possible. I regularly ran my code on old, outdated hardware to make sure it ran fast in low-resource environments. I tried to take advantage of parallel processing and every other trick I could think of.
But it seemed that no matter how much faster I could make the code run; I had trouble getting any potential users to care about that aspect of the code. I could make it 10x faster than their existing solution; but if it was missing even one feature their old one supported, they would reject it even if that feature was not that important.
The code was especially efficient at handling unstructured data (since that was its primary purpose), but the metadata management features I built in turned out to be extremely efficient at managing structured data as well. When I started benchmarking it against major databases it was performing very well (e.g. see it compared to SQLite: https://www.youtube.com/watch?v=Va5ZqfwQXWI). Still, it has been very slow to attract attention in spite of its speed.
We can complain about slow, buggy software all day; but we will be stuck with bloated, inefficient code if we don't put our money where our mouth is and support code bases that focus on small, fast code.
Figuring out a quick bugfix is like solving a puzzle, so is figuring out the right combination of flags for a cli command to do what it needs to. We subconsciously enjoy creating puzzles for other devs to solve, and when they figure out how to solve it, they feel good and like the tool we developed. It’s a vicious cycle of puzzle making and puzzle solving.
We make candidates solve puzzles to get a job!
But interesting puzzles aren’t usually the best solution to a user need. Until we break out of the puzzle-solving mindset I don’t think software will get better. Using a simple tool to get a job done simply scratches a different itch than the one we’re used to.
Your Notion desktop app and Google Chrome both support embedding & displaying multimedia content that's controlled by people that you may not trust, but they can draw on decades of engineering to sandbox that content. They can independently be updated without worrying about a centralized `flexbox.dll` that may or may not be the right version. They do not require building a new executable to make the vast majority of UI changes. And the cost is simply storage space and initial download bandwidth.
We can look with rose-colored glasses at an era of "every byte of assembly has been hand-crafted." I, too, look in awe at what was achieved with such things as https://github.com/chrislgarry/Apollo-11/tree/master/Luminar... . But that software, per https://en.wikipedia.org/wiki/Apollo_Guidance_Computer#Softw..., took 1400 person-years of work.
We have to compare apples to apples - the abstractions we have today would not prevent such a piece of software from being built, and indeed would allow us to build that exact software, even bit-for-bit the same, much more easily due to abstractions on our tooling itself. We have not departed a world where, given a nation-state budget, one could pay for 1400 person-years of work and create the AGC (though one might make arguments about the distraction levels of modern society, but that's a different thing entirely).
But we also exist in a world where I can build and ship a cross-platform video chat application in an afternoon (well, not counting app store approvals) and be reasonably confident that my app will be compatible with, and secure on, practically any computer or mobile device sold in the past half decade, regardless of how many other apps may have been installed on each device. I'd venture to say that Apollo engineers would, and do, find this aspect of our world fascinating, too.
Cars cost around X * $10,000 each. Houses cost Y * $100,000 each. The author is ignoring the economics of producing real world goods.
What does disappointment me about this industry is that we haven't found or invented some low-code app builder that is actually good enough for most use cases. I feel like we really should be spending most of our time as logicians who encode business logic, but we spend way too much time churning through supporting technology.
But every app builder I've seen runs into the same problem, that complexity scales exponentially in complexity a way that code doesn't have to. So it quickly becomes better to have built the dang thing from scratch.
And it's not like I can think of anything better. So it feels like we're missing something fundamental, probably to do with how we imagine user interfaces. Hopefully LLMs open the door to something better here eventually, and I'm not at all saying that chat views or plain speech are the best user interfaces we can do.
The only real way to "fix" that is for the tool to already know a lot about the problem domain but that means the tool is limited in scope and things become a lot harder once you try to go outsinde the things it's designed to do.
Executable specifications face the same problem. Seems like a great idea in theory to get the client / stakeholders to write a specification in a form that can executed to show the system does what's wanted. But very difficult to get them to do it. They come up with all sorts of complaints about the tooling but the real problem is that they don't want to precisely specify what their requirements are including edge cases but be vague and handwavy...
If you're going to criticize the state of software, you have to:
1. Demonstrate you understand the systemic incentives in place that encourage this behavior,
2. persuasively argue why this condition needs to be improved,
3. and propose concrete policies or incentives that counteract these tendencies.
Otherwise it's just whining about something you don't really understand, and the proposed "solution" is to just start all over because this time it'll be different I swear.
> The software industry is arguably one of the most productive spaces that the world has ever seen.
I would argue based on personal experience that majority of software that comes out of the industry is unmaintainable garbage. The reason it is acceptable in most cases is that the barrier to entry is low and there are few consequences of things going wrong. Quality goes up significantly when consequences become real. At any rate, I would not call the software industry "productive".
Then it is acceptable. You're making a moral value judgement because it's not up to your personal standards, but that's not relevant for whether or not the software accomplishes what it set out to do.
> At any rate, I would not call the software industry "productive".
This is indefensible, given that basically the entire world runs on software these days. Again, I think you're making some sort of subjective value judgement about the perceived "quality" of the software, while ignoring what it has enabled.
It obviously hasn't, there is still so much low hanging fruit everywhere.
And don't think this problem is unfixable, we will fix it at some point via standardization and each whiner is a data point that helps us get closer to standardization. It happened to cars, planes, boats, tanks etc, those fields started out with a lot of whacky ideas that didn't fit but then designs got standardized and the only thing left to do was to optimize those standard designs.
Edit: But for example, whining gave is git, a fast standard version control system that everyone now uses. When enough people whine about something then it gets fixed, bigger problems needs more of it.
If your argument is that things are more complex then they need to be, prove it. Because it's like an old man looking at a Honda and going "things were so much simpler back in my day!!"
Why not? This is part of the problem I'm talking about: we have too many armchair software engineers that know nothing about extremely complex codebases making sweeping generalizations about how they "should be". Their solutions are invariably "let's get rid of most features" or "let's just start over and Do It Better This Time."
Communicating it was step 1
Now what do you expect to happen?
You can wait for others to step up, and help you make your vision happen, but the call is this - have a goal, fight for it, but make no mistake - you will always be chosing between your family, and your goal, and yourself - this is the true conflict of every moment.
RALEMOI - Read - and loved every moment of it!
Point being, you are living your OWN life, and in the end, you will want to be satisfied with what you did, and to a much lesser extent, who you feel you are now.
I'd say kudos, god speed, etc, but I personally believe, God bless, and I thank you for your work!
So many people shut off their critical thinking skills as soon as you rub a computer on it. (Whatever "it" is: cars, ponzi schemes, whatever.)
- - - -
The second major reason is that the IT industry is fashion-driven. We are more fashion-driven than the actual fashion industry.
It took fifty years for type-inference and -checking to break into the mainstream, not because it didn't work or wasn't useful but just because it wasn't fashionable.
- - - -
I think the answer is, in a word, convergence. We have to converge on simple, reliable, proven systems (or watch the world melt into unbounded complexity and unpredictability.)
He uses a car analogy (how much efficiency we squeezed out of cars vs software) but misses the point - if a car was available that consumed half the gas or went twice as fast, I’d buy it!
If a computer / OS was available to me that was so much faster / more efficient than what I use… turns out I don’t really care and neither does anyone.
I am writing this on a 6 year old iPhone X that I got after my wife upgraded to the iPhone 15 at the same time my toddler drowned my Pixel 6 pro. The iPhone X is noticeably laggier than the 15 or the pixel but it doesn’t matter enough to go upgrade. And ditto for my 10+ year old PC. Point being, if I as a consumer am not bothered by the perf I get to even just drive down to the store, manufacturers would be dumb to over index on it
Obvious this is “just me” but if people really cared about a phone that boots in a second instead of 30(his example) there would be a market for it but the fact is nobody reboots their phone and it doesn’t matter. On the other hand if I had to wait 30 sec to drive my car and another manufacturer reduced that to 1, I’d switch.
TLDR - yes it’s inefficient and no it doesn’t matter. Those old systems he’s talking about were “efficient” because they had to run on hardware of the day, and increased requirements meant decreased market size - ie it really mattered! I am sure someone bemoaned the bloat of win95 that couldn’t run on his beloved 286.
Efficiency is one dimension. If I couldn't run calculator on anything but the latest Pixel / iPhone, that would be clearly insane. But it's not the sole dimension - if my ambition is to create something that works well for millions or billions users, hand-crafting Assembly may not be the right tradeoff.
Look how bad the self checkout experience is. You might say “if people cared, they would shop elsewhere”. But people want to buy food more than boycott a store with bad software.
I would say that bad checkout matters - in the way that I am talking about mattering - because it does effect a non-trivial amount of behavior.
First, I am much more likely to opt for self-checkout at Whole Foods vs in my town's supermarket (that I otherwise like) because the WF experience is pretty smooth while at the other store, the machine blocks until help arrives every X items. Does that matter? Well I think so, because (1) some # of people will go to WF over this store just because of that (2) some # of people will stand in a cashier line - costing the store money - because of this (3) some people will opt for delivery because of this - undermining the "local store" value proposition in the long run.
The above impact exists because in the bad case, self-checkout is nearly unusable. If it was just a matter of every item scan taking 2 seconds instead of 1, or needing to get human help once a year instead of several time per checkout - nobody would care.
Your reasoning assumes a fluid system with perfect observability into everyone's interests. Consumers can't even articulate their own interests fully -- it's impossible for vendors to respond properly.
Quality and high performing software exists when vendors elect to produce it. There are intrinsic motives and extrinsic.
Most quality products exist despite consumer demands not because of them. Don't fall for the "money incentivises everything" trap.
Can you give me an example of where this exists separately from "and we can sell more units before its performant"? I am open to that being the case, but wasn't able to think of a good example. Can you?
It bothers me often means "it matters to me."
Sometimes it is a signal of something bigger. Other times... it's just me. And it is hard to know the difference.
Everyone needs a car capable of reaching 120mph right? Moms and dads need giant utility vehicles to feel safe on the streets surrounded by giant pickup trucks. How is it "efficient" to drive trucks that are 2-3x the curb weight with less cargo capacity?
The problems occur due to business decisions not engineering
I recently updated Windows 10 in VirtualBox. According to htop, the process wrote over 17GB and I'm pretty sure it took more than 30 minutes using more than 100% CPU most of the time.
Or at least that's how it works for some languages. You cannot have just a portion of a jar included as your dependency. It comes all or nothing.
Tree shaking etc does exist for the frontend world but I am not so sure how much efficient that is.
The example omits how long it took to write the Python script. Is it accounted for in the calculated result of "41 years, 24 days".
It also assumes that memory usage, CPU usage and storage space are not relevant to efficiency.
There are other languages faster than Python that one could try besides Rust. Other languages might result in less memory usage, less CPU usage, less storage space and faster completion.
Plus, things in software tend to layer, so as the article point, maybe the script itself can be waited for a second if this is your final top task you are manually calling, but if it occurs in a long chain of calls it participate in a delay inflation.
I spent the 2010s in the desktop world. The Mac / Windows APIs are generally well designed. A lot of the abstraction and niceties comes from whatever frameworks are shipped with your application.
The browser forces you to use Javascript. Even if you use WASM, you have to use Javascript, because you still need to call back into Javascript to interact with many of the lowest-level APIs.
The browser UI is based on parsing complicated text; instead of the API and object-based models that we have on the desktop. It's really absurd, IMO.
Sad day
The market has clearly spoken in favor of the former.
After all, the goal of engineering isn’t to produce some abstract beautiful art but rather to create something valuable for regular humans.
Also the car and building analogies are poor because they are essentially the same design that has been optimized for decades. Indeed the only “new features” in cars are usually software driven and probably just as inefficient.
Demand software with features and performs efficiently.
If anything, the last several years in the software industry have proven hordes of mediocre developers really isn't a substitute for understanding how computers work.
The phenomena we're seeing now is VC money has dried up for all but those focused on efficiency, and the rats are scrambling to run to the other side of the ship before it sinks.
Same for web apps, why is Facebook, Gmail slow? I could accept it for new products but not for nearly unchanged products after all these years.
Btw: Gmail HTML was fast, so it can't be an infra problem, it's bad frontend programming.
But I get the argument. Software should be fast and reliable, but making it fast is not what the customer pays for, when it's good just enough.
Having the problem to always start at the bottom is what discourages people to start again. A company in the EU would be needed to build a smartphone and software on par with iOS and Android but we'll never get there.
For a lean and pragmatic text editor look at Helix, Kakoune, even NeoVim or Emacs.
I think this really highlights the problem. Would it even be possible to say this about software? Perhaps theoretically, but practically?
Thermal efficiency is well understood. Internal combustion engines are well understood. Every non-trivial software system, while using some common building blocks, is incredibly unique and decidedly not well understood.
We don’t refactor, why not?
Bloat is a default state in problem solving. Yes, shipping fast / MVP feeds it.
But refactoring is how all the highly optimized systems we have exist.
So why is refactoring so rarely done?
Because it almost always fails, outright.
Most refactors never make it out the door.
A few will succeed in shipping, but being worse than the original product.
Even fewer will reach feature parity.
Refactors that are a net positive are incredibly rare.
One of the reasons I’m rooting for AI powered tools. It’s a hopeless cause without them.
The first iPhone/Android were great innovations. And subsequent iterations occasionally added better features -- but not each year.
Phones are one example, but all we are doing is shoving more carbon the air, putting more trash on the streets and land fills, more water for datacenters, more plastic and chemicals in the oceans and our bodies.
Today is infinitely better, albeit more complex. I couldn't stand even thinking of developing any of the software I work on today with a 1990s PC - the thought is just inane. Let alone developing without Stack Overflow, or even now, just getting CoPilot to do it for you.
Loading times and such can be a bit long from time to time, but that's just because wait times are keyed to how much people are willing to wait, so the waiting time distribution is centered on that value. We could have subsecond wait times for everything, but people are ok to sacrifice a bit of time for cheaper costs or more functionality or any number of options.
These kind of articles have been popping up monthly on HN and I'm tired of them, but I get it - computers aren't perfect and the complexity of the world is insane, and while I wouldn't use a 90s computer, I would love to be working on 90s problems again - I spent almost all of my time writing new code, because the world needed that code. Now it is mostly just integrating and tweaking, and the big problems are figuring out what people want and need and if there's a way to get it to them. You don't need to write a rasterizer or a 3D renderer or a database or any number of fun projects, because there are a million different versions of those out there that would take years or decades to replicate.
Bug the hardware and software we are using? Orders of magnitude better! And fast - holy hell is it fast. Just because you don't understand what it is doing doesn't mean it is slow.
The reason software is slow is because people write shit code, with or without abstractions. Too much db/api traffic, suboptimal algorithms etc. Fact is, most developers just suck at programming. Which makes a lot of sense at least where I am because we don't have any rigor in our craft. People go through a bachelor's degree learning as little as possible and the bar for passing is embarrassingly low. They get a job and the employer just puts them to work, personally I was placed alone on a maintenance project for a large application. Nobody reviewing my code, nobody else with any sort of domain knowledge to lean on.
In other professions, people have apprenticeships and such where experienced peers teach them the things they need to know and make sure they do things right. In software nobody gives a shit. Some QA person goes into the app and clicks a button and if it seems like it works they ship it.
People are stacking shit on top of shit, literally just writing legacy code. Because nobody teaches people how to do things right and nobody checks their work to see if they have done things right.
In software, doing that is boring. So we constantly invent new solutions. Because evaluating and reviewing products and maximizing quality is boring and hard, while hacking out new things is fun and cool.
I can relate to the disenchantment but I found the argument here to fall flat.
He has SOME editor in mind, I'm just curious what it is.
I understand that author was referring to the concept of a minimal version that does just text editing and nothing more. Add features to anything and it will stop being simple and easy.
However, the author might also be generalizing and referring to "MS Word" as a text editor, which a lot of people unfortunately do. This is where I would disagree with the author's premise.
Sure, if you add non-existing features then the real argument assessing apps without those features would fall flat
About the best you can hope for is get into a place that’s complacent because otherwise it’s daily wtf stories all the way down. The complacent place will be a daily wtf too but at least people will have bread and circuses
Although I may never have time to actually work on it. Especially since it will be a complete waste of time unless I can get a huge number of people to adopt it.
How much is saved making the code more efficient? Now remember, their employer only cares about this in terms of their dollars.
Vs.
How much does it cost to make the program more efficient. Remember that every change risks introducing new bugs that could literally put a customer out of business.
There’s strength in numbers.
That would make an interesting retirement home, you're only allowed in if you're from the Software Engineering industry and willing to work on open source software.
But a feature complete product, with perfect performance cannot be sold twice.
I won't need to buy a PDF reader ever again, now that I have SumatraPDF, for example.
It’s actually funny how easy reducing bloat and slowness is with even a small attention to it compounded over time.
I only hope that FOSS software can learn from this
Oh I can tell you the answer already. It's 'no'.
> Ever wonder why your phone needs 30 to 60 seconds to boot? Why can’t it boot, say, in one second?
Simple, run systemd-analyze blame, disable all services and boot in under a second. Of course now nothing works and you can't access the system to check how long it took...
Your phone OS is just bloatware and you and everyone else knows it, no need to make it seem like it couldn't be different right now.
But sometimes bloat is also good in a way? Micropython comes to mind. It may be the most laughably absurd way to destroy one's performance on a microcontroller but the abstraction it offers is really nice to work with. The problem is, I suppose, that we're in a recursive spiral of abstraction and each additional layer has to take into account all possible cases, drivers and whatnot for the next one. Hence the bloat. But there is definitely something hilarious about running an OS that runs an OS VM, that runs a container, that then runs another VM to run an interpreted language.
One day we'll be able to chatgpt ideas directly into machine code and get both speed and efficiency, but until then I don't see how one can avoid long dev times without working at a higher level.
Here is my project https://github.com/imvetri/ui-editor.
It started as a challenge to find single syntax to generate code for all framework, then it scales to low code, and right now at design to code
That's why I use Emacs. What am I missing?
My current computer boots in seconds.
In my experience it seems a good deal of bloat has to do with resiliency. Most desktop applications don't completely crash the entire system when they contain a memory access bug. They just crash. That doesn't come for free.
Let's say you want to go outside and cross the street. In order to do that you need to put on your shoes and lace them up so that you don't trip and fall. You do this and while crossing the street one day you fall and discover that your lace came untied. In order to prevent this next time you decide you will look down after every step to make sure your shoes are still tied.
This is how a lot of modern software works: we check if our shoes are still tied.
One way to fight against this, I suspect, is that we have to think more clearly about correctness. Back when Multics and Unix were being developed under the same roof at Bell Labs the Multics folks were wringing their hands over error recovery: the kernel had several "rings" and handlers could be registered... but there were always edge cases. Unix on the other hand? Just let it crash. Since then there has been a lot of research and development into how to formally specify systems using precise, checkable proofs. I think there are certain kinds of performance gains we can only make when we don't have to keep checking if our shoes are tied and those can only come from languages and tools that let us formalize our programs.
This is not my idea, it's from Conal Elliot who's awesome and smart [0].
The other source of bloat is the kitchen-sink effect. Writing software is time consuming. Most businesses don't want their developers writing low level drivers and optimizing memory usage. They want to get a product in front of consumers and get paid because the business might not even be in business in 9 months if you don't start shipping and making revenue. Fortunately there are a great number of kitchen-sink software frameworks and stacks of libraries for most development tasks... which include more code and resources than your application will use... but again, convenience and speed dominate. The average phone in 2018 had something like 4GB of RAM and ~32GB of HDD space. If your app used up a gig of working memory and took up a gig of space but you got it out in a few months by hiring JS developers who knew react native for less than what it would cost to hire Swift/ObjC developers to write the perfect app from scratch? We know what most businesses will choose.
[0] https://www.youtube.com/watch?v=k6rY5Mvx84E&list=PLOvRW_utVP...
This is provided by hardware and basically free. Besides, computers aren't slow because of kernel bloat. Linux, OSX and Windows have serious issues but all major software problems are in user space.
This is the "user space" bloat.
Resiliency is one of those things that's baked into every layer of the stack seems to be cumulative. Research into lock-free algorithms in order to improve efficiency requires correctness and there are still places in the OS level and user space that would benefit from it.
Lock-free algorithms don't help much with performance. Locks are very cheap and your PC spends very little time spin-locking. Even interrupts and thread-switching (which is much more expensive) aren't that big of a deal nowadays.
Is there performance left on the table from adding resilience to systems in your view?
Take sqlite for instance. sqlite is very resilient, gives you transactions that you can roll back, and on top of that, storing small files in a sqlite database can be faster than using the filesystem directly. You get resilience AND performance AND a boost in productivity.
Edit: it's like climate change: individual decisions that are all locally justifiable according to some decision framework, but add up to a world which is objectively crappier than a world in which we did collectively behave this way.
The whole ecosystem of modern programming and software is just insanely opaque. As an enduser you have very little clue who is to blame for an error or a slow machine.
Imagine your car would not been build by a single company, liable for the whole product, but you would buy the individual components from twenty+ different companies, rangin from ibm to small startups. No central planing. They all have their own take on it. They just set a few standarts for how the things bolt up. It would be the same mess.
Like in the earlier days of analog tech, ransomware attacks today are blamed on bad luck. Just put up some Antivirus gemstones in your Outlook and don't forget to get your security christened with some certifications.
But to be fair, people seldomly die from slow software.
We have a contractor who built a system on Azure that I'm about to take over. I was complaining about how slow RDP'ing into the Azure machine that runs Visual Studio and SSMS is. The contractor said it's quite fast for him so I sent him a video of what I see. In that video, you can watch parts the window as they are painted. Same for executing a query in SSMS. Now, this guy is a fantastic engineer but, I had to chuckle a little when he saw the video and replied, "Yeah, that's how fast it is for me too."
After two weeks of fighting with SSIS and RDP speeds, I eventually gave up and rewrote it in Clojure in less than a day.
Modern text editors have higher latency than 42-year-old Emacs.
Visual Studio Code is about the only Microsoft product I have any respect for yet, for the most part, I've gone back to Vim as my daily driver. Even the contractor I mentioned above said he uses it a lot of the time.
The iPhone 4s was released with iOS 5, but can barely run iOS 9.
I have had so much respect for Apple in the past for saying openly, "This release is going to be lacking in features because we're going to try to make things run better." Yet, when was the last time they did such a release for any of their platforms? Given some of the oddities I'm having with Sonoma, I'd say it's time.
Windows 95 was 30MB. Today we have web pages heavier than that!
I spent 2/3 of my career trying to make web applications as good or better than native. I gave up on that about 10 years ago after realizing that a) the webplatform was designed as a document sharing system, not an application platform and, b) as much as I love Javascript, Node and NPM are a dumpster fire. We need to call it a day and do something else. My vote is for something akin to Flutter.
Also, the shear tonnage web application frameworks are a clear sign to me that it is a problem that can't be solved. They all eventually devolve into a bloated mess.
Related: Nobody thinks compiler that works minutes or even hours is a problem.
Am I the only one that thinks compiling dynamic, scripting languages is insane? Jeff Goldblum called. He want's his Jurassic Park quote back.
It just seems that nobody is interested in building quality, fast, efficient, lasting, foundational stuff anymore.
50% of the blame needs to be put on the stakeholders. Too many of them don't understand (and, often, don't want to) and demand the product be delivered cheaply and done yesterday. The current state of software is what attitude that produces.
Better world manifesto
100% agree.
1. Waaah! Much badness! (lots of it)
2. "We must do better"
3... well, that's it. No concrete suggestions for 2.