[HN Gopher] Laws of Software Evolution
___________________________________________________________________
Laws of Software Evolution
Author : thunderbong
Score : 72 points
Date : 2024-04-27 02:27 UTC (20 hours ago)
(HTM) web link (two-wrongs.com)
(TXT) w3m dump (two-wrongs.com)
| bruce511 wrote:
| For a long time, doing training of programmers, I'd explain that
| bugs come about when we write code. Code left alone "does not
| rust".
|
| In the last decade I've swung the other way. While the code does
| indeed "not rust" it does decay.
|
| Primarily this is because software now is more integrated.
| Integration means communication and there are changes happening
| all the time. SSLv3, TLSv1, went away. XML became JSON. And don't
| get me started on SaaS APIs that have a "new version" every
| couple of years. And yes, the elephant in the room, security.
|
| Unfortunately lots of developers in my age group believe in "if
| it's not broken don't fix it". They are the hardest cohort to
| convince "update things even they're important. Updating when its
| _urgent_ is no fun at all. "
|
| There's no habit as hard to break as a best-practice thats turned
| bad.
| petabyt wrote:
| The code running on the ECU on my 34 year old truck hasn't
| rusted ;)
| filmor wrote:
| Because it doesn't talk to other, potentially changing
| systems. As soon as an application is networked, it requires
| maintenance.
| quadhome wrote:
| Would that ECU pass modern emissions?
| pif wrote:
| Much likely not, and that's a good thing, because nobody
| has yet found a way to limit emissions without seriously
| impacting performance (especially concerning responsiveness
| and low regime). May be damned them who invented drive-by-
| wire!
| datavirtue wrote:
| If you had an appreciation for emissions technology and
| policy you would be able to see how it has swung past the
| point of it's intended purpose. People are dismantling new
| engines to find all kinds of issues that will severely
| limit the useful life of the vehicle and/or cost the
| consumer a ridiculous amount of money in repair or
| replacement costs.
|
| The lengths to which manufacturers have gone to "hit the
| numbers" has resulted in these major deficiencies. This has
| all formed out in the last decade. Previous to that, a lot
| of the emissions standards had a positive affect (in most
| cases).
|
| The automotive manufacturers and the regulators are
| colluding without enough transparency and it has corrupted
| the process.
| necheffa wrote:
| Someone already mentioned that your ECU doesn't really need
| to talk to other systems (besides perhaps via the OBD-II port
| with a well established, industry standard, backed by
| regulation protocol).
|
| And I'll also add that at no point are you ever going to need
| to flash the ECU with updated firmware.
|
| So while a cute example, it isn't really a practical example.
| Typically when people complain about "code rusting", it is in
| the context of a codebase that needs to adapt to the world
| around it; whether that is communicating with other systems
| or even just accepting new features within its own little
| fief.
| necovek wrote:
| I don't think it's as simple as that.
|
| Some of the modern ecosystems have gone entirely bonkers (think
| nodejs/npm): hundreds and thousands of dependencies for the
| simplest of things, basically an unmanageable "supply chain".
|
| Sure, we can talk about what's good approach to update and
| dependency hygiene, how packages should "freeze" their
| dependencies, how should breaking changes be communicated
| through version numbers (or not), but we've seen the rise of
| the non-NIH that can't bother to implement 5 lines of code.
|
| If you commit to update whenever there's a newer version of any
| dep you are using, you commit yourself to a world of pain and
| fighting even more bugs.
|
| I actually believe LTS repos of public repos (PyPI, NPM, ...)
| could be a decent way to earn some money in today's dependency-
| heavy world.
| taneq wrote:
| This overacceptance of external dependencies and
| compatibility-breaking API changes all started with the shift
| from software-as-product to software-as-a-service. Honestly
| it feels like the resulting churn and busywork is on some
| level a deliberate ploy to create more job security for
| software devs.
| IshKebab wrote:
| That's really a separate issue. Even if all of your code is
| first party and you've been crazy enough to write your own
| TLS library, XML parser, etc. all the things he said still
| apply because most code lives in an ecosystem of other
| systems.
| PeterisP wrote:
| On the other side of the coin, if you freeze your
| dependencies and commit to not update whenever there's a
| newer version of any dep you are using, you commit yourself
| to having to continuously (and rapidly!) evaluate all the
| security advisories of all those dependencies to see if there
| are any bugs you have to mitigate before your system gets
| exploited.
|
| You can't simply choose to never update any dependencies -
| the only question is how you decide when and which updates
| will get made, or delegate that decision to others.
| userbinator wrote:
| _Integration means communication and there are changes
| happening all the time. SSLv3, TLSv1, went away._
|
| The problem is a lack of modularity and standardised interfaces
| where it matters (and modularity where it doesn't, causing
| additional useless complexity), and incentives that reward
| planned/forced obsolescence.
|
| Also related: TLS 1.3 on Windows 3.11:
| https://news.ycombinator.com/item?id=36486512
| vegetablepotpie wrote:
| I'd say interfaces are _part_ of the problem. People are
| happy to change interfaces when it makes the implementation
| of a component easier. I've seen interfaces change without
| notice and this imposes maintenance overhead.
|
| I'd say that _complexity_ is the other part of the problem.
| As developers, we like to organize functionality into
| packages, and version them based on the type of changes we
| make. We like layers of abstraction to contain classes of
| problems to work on them independently. But all software is a
| list of instructions, and all the ways that they can interact
| cannot be categorized in a Symantec version number, or a unit
| test. Subtle changes can break functionality in surprising
| ways.
| eddd-ddde wrote:
| An interface that changes because of the implementation is
| not really an interface.
|
| I can change from ext2 to btrfs and my program won't die
| because open and read are a good interface.
| f1shy wrote:
| If 10% of people doing SW would understand this, the
| world would be much better.
| cpeterso wrote:
| I fear good ol' fashioned information hiding is being
| forgotten in modern software design. Systems are
| increasingly complicated and developers are busy just
| trying to get all their code to fit together to worry
| about the difference between an interface and
| encapsulation.
|
| https://en.m.wikipedia.org/wiki/Information_hiding
| oooyay wrote:
| One of my more favorite forms of testing is offline E2E
| testing. Python and Go are very adept at doing this kind of
| testing, which is nice. The idea is that you use exposed
| APIs (read: anything for consumption. Could be REST but
| also could be important packages) just as the user would
| use them. The nature of testing is that it captures the
| discreet contracts you're mentioning by reusing the API
| itself and ensures them.
|
| There's a discussion to be had that's the volume of E2E vs
| unit tests, but that isn't this discussion.
| isityouyesitsme wrote:
| Agreed. your parenthetical comment explains the tension.
|
| The only solution is to have a crystal ball.
| amboo7 wrote:
| Code rusts via the loss of information about it (memory,
| documentation...). If it cannot be maintained, it is a zombie.
| necheffa wrote:
| > Code left alone "does not rust".
|
| I think I am uniquely qualified to speak authoritatively on
| this subject as I regularly work in code bases dating back to
| the mid 1950s (nearly 70 years old if you are counting).
|
| Code left alone absolutely does rust. Everything around the
| code changes, you can wax philosophically about how
| "technically the code didn't rust the world did", but at the
| end of the day that old code aged into a position where it no
| longer functions optimally or even correctly.
|
| Just to tease with an example, the original machine some of
| this code was written for only had a few kilobytes of memory,
| half of which was taken up by the OS and compiler. In order to
| fit the problem you are working on into memory, they
| effectively wrote a custom swap allocator that looked and felt
| like you were using in-memory arrays but were actually using
| tape storage. Fast forward to today where we have a single
| compute node with 128 physical CPU cores and a terabyte of
| memory, the code still diligently uses disk storage to minimize
| RAM consumption but runs like dog shit on a single thread
| anyways. Not to mention all the integers used to store pointers
| have had to be widened over the years as you went from 48 bit
| words to 32 bit words to 64 bit words.
| esperent wrote:
| > The software I encounter most is software that interacts with a
| changing world. It's software that needs to adapt to other
| software, but critically, it needs to adapt to its users - to
| people! People change their attitudes and processes in response
| to the environment, and the software needs to adapt around that
|
| Over the last few months I've been evaluating several POS
| solutions. They come in two varieties: fairly modern SAAS types,
| and super old school software (feels like it's from the nineties
| but the two we evaluated both seem to have been created early
| 2000s) with a local database that is synched online every so
| often.
|
| I can tell you that while the old stuff works, it doesn't feel
| comfortable to use in a modern environment. One example took
| around 30 minutes to install on my modern workstation laptop with
| many steps (and the guy demoing commented in surprise how fast it
| was!). And that's what software used to be, twenty years ago.
| Enterprise software, I mean. Everything was clunky and needed a
| guy who understood it or at least following long complex
| documents and spending several hours working through the install.
|
| Meanwhile, the SAAS varieties have zero install time because I
| can use the web interface instantly, or install a client app in
| around 3 minutes. It is much smoother and with a far lower
| barrier of entry. I've only dealt with the install but the UI is
| equally different and more intuitive on the modern apps, often
| with guided tutorials and setup wizards. Although to be fair,
| some of the modern apps are not great either. But I'm thinking
| about the best modern app vs the best old-school app while I
| write this.
|
| Both of these styles would _work_ as a POS system. But the old
| style feels very clunky and uncomfortable to use.
|
| I still do deal with lots of clunky installs, databases, long
| technical documents. But that's because I'm a developer. Non-
| technical users are far less accepting of these things than they
| were twenty years ago and the software has to be upgraded to deal
| with that.
|
| We chose one of the smooth and well documented SAAS options. I've
| been looking around at what other local businesses use and
| anecdotally it seems like 90% of them also did and only very few
| use the older style software - and maybe those have been using it
| for several decades.
| jasongi wrote:
| Yet, this is also the tragedy of modern software. While a fancy
| SaaS POS system will be fast and easy to install, the legacy
| local database version is going to keep working throughout an
| internet blackout (with cash), a power outage (via backup
| power) or an outage of the remote server.
|
| I doubt anybody is losing customers over a 1s delay in the till
| opening or a POS server syncing the day's transaction after
| close. But having worked in retail - the one time you get a
| call from head office is when there's "loss of trading" - it's
| a bigger issue than theft.
|
| I remember there being an entire tourist town that was
| suffering economically because during peak season, the mobile
| phone tower was saturated and merchants could not process card
| payments. You can't even use click-clack machines anymore with
| modern credit cards.
|
| Now... working offline is entirely doable in a modern tech
| stack too - but I somehow doubt most modern POS products
| support it well.
| esperent wrote:
| The modern SAAS versions all work without internet using the
| client app. As we are in Vietnam, I don't think any business
| would ever choose a POS solution that didn't work without
| internet or via battery power during an outage. So there's no
| loss of functionality there. There are power outages around
| once a month, scheduled or unscheduled, not to mention storm
| season which has more frequent outages, sometimes for several
| days. So this functionality gets well tested.
|
| All banking solutions - as well as the POS system - can work
| on mobile data and that usually is fine during an outage. The
| only time mobile data failed in recent years was after a 3
| day power outage following a typhoon, when I guess _their_
| batteries failed. By that time our business was pretty much
| shut down due to supply issues anyway.
|
| So basically, as long as the battery or generator lasts, all
| of these POS solutions will perform equivalently.
|
| Edit: and to further clarify, I don't think there are _any_
| features that the old schools apps have that the new ones don
| 't. Unless you consider a local database or not using a web
| browser as features (which is valid but not my view). While
| the newer ones tend to have a much stronger focus on
| accessibility (probably because they are basically web apps)
| and translation.
| brabel wrote:
| Why were they "installing" stuff on your laptop instead of, for
| example, using Docker, or even better, Nix, which are tools
| that solve this entirely?
| esperent wrote:
| Why would I know the answer to that?
| ozim wrote:
| Are they?
|
| I have to install docker still, I have to configure
| networking to access the thing that is in the container
| because defaults work for demo, but in production env you
| still have to have bunch of stuff in front of docker.
|
| If I have defaults for the system in database that I need to
| change so anything that is in docker actually works.
|
| With docker/kubernetes I have one more thing to worry about
| and still lots of config that doesn't go away "because
| docker".
| GuestHNUser wrote:
| > but critically, it needs to adapt to its users - to people!
|
| In principle, I want this to be true. But, in practice, I think
| products change because the teams that built a product need to
| justify their continued existence within a corporation. Slack's
| last few rounds of UI changes for instance, has been a net
| negative for me, the user. Why can't I split several channels in
| the same window anymore? Why did they add a thick vertical
| toolbar that I don't use and can't remove? Not for my benefit,
| that's for sure.
|
| p.s. Kelley not Kelly is the correct spelling of his name.
| cqqxo4zV46cp wrote:
| I think that it's very important to remember that most
| software, by count, is not some deep-pocketed VC-funded / big
| tech company's baby.
|
| If HN people stopped working for HN companies then they'd see
| that most of the behaviours they complain about, on HN, are not
| universal inevitabilities.
| ozim wrote:
| You are also sure that those changes were not beneficial for
| someone else in a way where your single opinion is outvoted?
| wavemode wrote:
| I'm sure it worked lovely for whatever biased focus group
| Slack Inc hired to review the changes. But where I work the
| redesign is pretty much universally hated.
|
| I would've thought a company centered around developer
| culture would understand the concept of not fixing what isn't
| broken. I guess pencil pushers have now fully taken them
| over.
| jongjong wrote:
| I wasn't familiar with Andrew Kelly but he is spot on. It is a
| corporate conspiracy where the problem is manufactured and then
| later solved in a way which introduces yet more problems. It took
| me almost a decade years to figure this with high confidence.
|
| This article is falling into a trap stating that 'requirement
| changes' are to blame for constant software rewrites. Good
| software architecture doesn't require full rewrites precisely
| because it anticipates requirement changes. That's the entire
| point of software architecture. Unfortunately, almost nobody has
| experienced good software architecture. Even among the very few
| who will encounter it, most of them won't recognize it because
| either they are not competent enough to appreciate it or they
| simply won't stay on the same project long enough to observe the
| benefits and flexibility of its architecture.
|
| So yes, I think it definitely looks like a conspiracy. I've
| encountered many developers in my career who have had a tendency
| to over-engineer and create unnecessary complexity; they are
| often promoted within companies. Not only in agencies and
| consultancies (where the incentive to over-engineer is clear;
| more bugs = more repeat customers), but also in other large
| corporations and even non-profits.
|
| There is a significant shortage of competence both on the
| developer side as they are unable to produce good architecture
| but also on the management side as they fail to recognize good
| architecture and accurately reward talent.
|
| Most software developers and managers will outright deny the
| existence of 'good architecture'. They are such a large majority
| that their voices completely obscure the voices of the (guessing)
| 1% who know better. The voice of mediocre developers, propped up
| by short-term financial incentives, is much louder than the voice
| of excellent developers who pursue longer-term goals.
|
| Unfortunately, if you're a top 1% software developer, the
| industry feels like Idiocracy, except for the crucial fact that,
| in Idiocracy, the idiots are just smart enough to identity who
| the intelligent people are.
| misja111 wrote:
| There is a problem with the notion of 'good architecture', and
| that is people tend to have strongly different opinions on what
| a good architecture is.
|
| Take a basic web application as an example. In the last 20
| years, we went from n-tier, to generated frontend using some
| template framework, to rest server + js frontend, and recently
| generated frontends have become fashionable again.
|
| Or for example enterprise architecture. We went from a bunch of
| monoliths with ad hoc interfaces, to service oriented
| architecture, to microservices, and now the trend goes to
| monoliths again.
| anyonecancode wrote:
| I don't know if "good" architecture can be defined, but
| "consistent" architecture can. It's the lack of the latter I
| often see and that causes the most issues. Inconsistent
| architecture makes it very difficult to understand the
| overall system, which makes changes risky. There will always
| be mismatches between what our software does and what we want
| it to do -- either because we got it wrong the first time, or
| because conditions have changed. The most important attribute
| of software is it's ability to change, and for that
| consistency is key, as it makes it possible to actually
| understand the software. If you have variable names that
| don't correspond to the data they story, a hodge podge of
| different ways you are making network communications, state
| being stored, mutated, and accesses willy nilly... it's going
| to be a bad time. Have a vision of how it's all supposed to
| work, stick to it, and change deliberately as needed.
| datavirtue wrote:
| I just clarify managements priority before making decisions. It
| won't be framed as short vs. long-term but it's always clear.
| What are devs going to do, ignore the business realities and
| stomp off to create their masterpiece?
| ChrisMarshallNY wrote:
| In my case, maintaining software usually ends up reducing
| complexity. Many bugs, are because I wrote an overcomplex kludge,
| which I only recognize upon reflection.
|
| Also, it's not just users and their environment that changes.
|
| I have had software break, when Apple comes out with an OS
| update, and I had, for example, relied on a certain behavior that
| was not specifically dictated in the API.
| fl0ki wrote:
| I agree with all of this, but even this is overlooking a simpler
| point: the software probably wasn't perfect in the first place.
| Even a few-line algorithm, isolated from any APIs or IO, can have
| subtle bugs. Remember the headlines when people noticed that most
| textbook implementations of binary search had an integer overflow
| bug?
|
| If you take any old C or C++ code, for example, it's extremely
| likely that it has at least one construct with Undefined
| Behavior. Many instances of that binary search issue had outright
| UB because of signed integer overflow, and most code has much
| more subtle UB than that.
|
| The more time passes the more likely that UB manifests with a
| newer compiler, a new OS version (especially if it's Library UB
| rather than Language UB), a new CPU family, etc.
|
| This is nobody's fault as such, UB wasn't well understood until
| compilers became aggressive enough to actually exploit the letter
| of the standard rather than the common intuitions. Even so, good
| luck finding old code that would pass modern scrunity.
|
| In the unlikely case that a program had absolutely no defects of
| its own at the time it was written, it could still use a
| deprecated API, make a stale assumption that increasingly limits
| its interoperability and versatility, fail to utilize modern
| resources like many-core CPUs and RAM larger than entire
| enterprise disk arrays used to be, etc. Any number of things
| could merit improvement without a single bug or change to
| requirements as such.
| photonthug wrote:
| Interesting comments, I was expecting a roughly 50/50 split for
| folks who buy into the "intrinsically hard" story where Reqs
| change or highly integrated systems just tend towards breakdown
| vs the "enshittification" story where software quality just falls
| victim to planned obsolescence, greed, or simply pointless
| changes caused by fake jobs and the typical make-work.
|
| The third explanation is practitioner incompetence and
| indifference. Regardless of whether we are talking apps or apis,
| it's never been easier to keep around old versions and skip the
| bitrot but most people just don't know how to do that. This
| doesn't mean it's hard, just that they'd rather screw over some
| subset of users than learn how to do proper versioning and
| releasing.
|
| I phrase it like this because I think it's a choice people make,
| and thinking about things like backwards compatibility and
| dependencies is seen as unsexy and just a thankless chore. If
| someone wants to dodge it then eventually some one else will get
| assigned to clean the mess. Next person will do just enough to
| escape the situation without really fixing it and so on.
|
| The attitude is basically "It's not like we're the ones who have
| to use this crap! Ship it", and it's present everywhere from
| corporate to open source, projects big and small.
|
| Part of it is a lack of pride/craftsmanship, but even senior
| folks are going to yolo their next release _sometimes_ unless
| there's some process in place that prevents it.
| gherkinnn wrote:
| > Code is malleable enough that we think of applying changes on
| top of existing code to get a new product, slightly different
| from the previous one. In this way, code is more similar to
| genetic material than other types of design.
|
| This is an interesting perspective and will take me some more
| time to apply to my understanding (see what I did there?). A
| first thought is how this condemns designing and architecting for
| an unknown future.
| PeterisP wrote:
| For code, future is neither unknown nor certain - we often do
| have a valid, informed opinion about what kind of changes are
| likely (or even inevitable on a schedule) and what kind of
| changes are possible but unlikely.
|
| For example, you may know for sure that some invariant is true
| in your market but not globally, so you know in advance that
| when(if!) your company expands, you'll need to change that
| thing in a specific way - but not in an arbitrary direction,
| that change is knowable even if you haven't yet spent the
| effort to know about its details.
___________________________________________________________________
(page generated 2024-04-27 23:01 UTC)