summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/blog/slowftware-development.md522
1 files changed, 137 insertions, 385 deletions
diff --git a/content/blog/slowftware-development.md b/content/blog/slowftware-development.md
index 0b40a8d..4995d59 100644
--- a/content/blog/slowftware-development.md
+++ b/content/blog/slowftware-development.md
@@ -1,144 +1,27 @@
---
title: Slowftware Development
-date: 2024-10-04
+date: 2024-10-06
draft: false
---
-# Going fast, slowly
-I recently came across an almost [10-year-old blog post][3] on Varnish HTTP Cache
-(which was released nearly 20 years ago).
-In that post, the author shares the LoC (Lines of Code) analysis of Varnish and talks about the average
-LoC per hour per developer and how the LoC metric has been used before to judge productivity.
+# Slow is Fast
+The fastest way to create high-quality software is to develop this software slowly and thoughtfully.
+It might seem counterintuitive, but by focusing on understanding the problem,
+designing the **right** solution, and refining it through iteration and simplification,
+ends up being faster in the long run.[^8]
-And although the content of the blog post is quite captivating, and although the LoC metrics themselves are quite
-interesting and worth looking at, (for example, ~22% is documentation and ~22% is testing), but ultimately what
-captivated me the most, is the following quote
-(which I hadn't heard before reading this post):
+Rushing to get an MVP out the door often results in poorly scoped projects and architectural design,
+technical debt, and "Big balls of Mud" -- architectures that are costly to maintain, and slow to fix.
+# Perfection Through Removal
> "Perfection is attained, not when there is nothing more to add, but when there is nothing more to remove." <br>
> --- _Antoine de Saint-Exupéry’s observation_
-**So how does a perfect software look?**
-
-It's a well-known fact, that software development is quite messy, and unlike any other branch of engineering, it's
-also the most tolerating failures and short-comings in design (it shouldn't, but that's a topic for another time).
-
-There is no perfect software, and there will be none in the future, but there are many good software products
-(and software developers) out there, and for anything good to develop, it needs time, **lots** of time.
-
-The time required is dependent on many factors, including but not limited to, the developer's previous experiences,
-the understanding of the problem, the time needed to theorize a solution, and the time to code that solution.
-
-The first factor, "previous experience," isn't controllable. (at least not for this post's purposes).<br>
-The last factor, "time to code," is the least important, it can be adjusted (with hiring) or planning costs for the
-estimated time required.<br>
-The other two factors are the most influential. And the ones that are affecting how correct the "time to code"
-estimation will be.<br>
-If you don't understand the problem at hand or have developed the wrong solution
-(whether it's technically the wrong implementation or design, or conceptually solving the wrong problem), the time spent
-grows (linearly at best).<br>
-
-So, _sometimes_ it's faster to be slower in understanding the problem, theorizing a solution, mapping the solution
-components to the proper design patterns, and then starting to code that solution.
-
-There will always be a discussion on the time this will take and how much market value is being lost because we
-are not reacting fast.
-That's not to -[anecdotally][9]- mention the cost of having multiple planes nose-dive
-because the software solution that needed to be implemented quickly to capitalize on the market wasn't properly designed
-with redundancies and proper quality control.
-
-Now you start to see how going slower is **faster** and **cheaper**.<br>
-So, how to "slowly" write the best solution?
-
-# The Agile Manifesto
-In 2001, _The Agile Alliance_, a group of 17 software practitioners met at a resort to discuss lightweight development
-methods (i.e., Extreme Programming, Scrum, Lean), these lightweight development methods evolved
-in reaction to the prevailing _heavyweight_ methods (often referred to collectively as waterfall).
-
-They wrote down the [Manifesto for Agile Software Development][15], and the 12
-[Principles behind the Agile Manifesto][16]. And although these lightweight methods already preceded the publication
-of the Agile Manifesto, they came to be collectively referred to as the agile software development methods.
-
-Few things have reached far and beyond the reach of the Agile Manifesto in software development, and fewer things
-have had more impact than the Agile Manifesto in recent years on software development and work methodologies
-(both good and bad).
-
-Over the years, there has been criticism and debate over the agile values, and how they can undermine various
-disciplines of the software development process, namely documentation[^1] and testing.
-
-Personally, I think that most of the criticism is targeted towards the interpretation or to be more specific,
-the misinterpretation of the agile principles. That's not to say that there are no merits to the criticism,
-but to actually inspect and try to correct the shortcomings of the agile framework.
-
-In an [article][18] titled, "**Have we taken agile too far?**", [Colin Bryar][19] and [Bill Carr][20] write about
-their criticism of the Agile process, especially in the crucial early stages.
-
-> Agile is a powerful process for product development, but many organizations are taking it too far and using it
-> to avoid careful planning and preparation.
-
-They elaborate on this deposition that "**Speed Isn't Everything**", they inspect a misinterpretation of the principle
-"**Sustainable development, able to maintain a constant pace**", where the focus is on maintaining a constant pace
-rather than being sustainable.
-
-> The fundamental problem with agile, as many companies use it, is that its relentless pace biases developers.
-> They want to get out a minimum viable product in only a few weeks, so they skimp on scoping out just what the
-> product should accomplish. Or worse, in our experience, they make two kinds of compromises.
->
-> First, rather than take the time and uncertainty to develop a new capability, they go with the skills they currently
-> have. They accept their existing constraints, which automatically limits the potential for a high-growth offering.
->
-> Second, they curtail their ambitions on the product. Instead of a major breakthrough, they tend toward only
-> incremental improvements on existing offerings. Or if they do go bold, their minimum viable product isn’t really
-> viable at all, so customers can’t give realistic feedback. The developers haven’t had time to do their homework
-> and prepare something that’s sustainable.
-
-In order to avoid these misinterpretations and reap the benefits of using agile, they suggest:
-
-> We’re not arguing that companies should throw agile out the window. It’s still a highly effective tool for product
-> development, especially software-driven offerings. Many of its principles and processes have been used successfully
-> by Amazon and other companies.<br>
-> ...<br>
-> The best solution, then, is to combine agile with something like working backwards. Amazon, for example, has learned
-> to use the working backwards process for idea development, but then follow agile to build and ship the product.
+The same applies also to software development. Simplicity trumps complexity.
+Clean, maintainable software is born from stripping down, not piling on. Yet, simplicity doesn't come quickly.
+It requires careful thinking, planning, and understanding the problem before jumping into coding.
-# Working Backwards
-
-Working Backwards is a systematic way of vetting ideas to create new products. It starts by defining the
-customer experience, then iteratively work backward from there until the team achieves the clarity of thought
-around what to build.
-
-In their book titled "[**Working Backwards**][21]", authors [Colin Bryar][19] and [Bill Carr][20], describe (among
-many other principles and practices) the "Working Backwards" strategy and how it was developed, its key tenets, and
-the practices that emerged from working backward (i.e., the banning of PowerPoint presentations at Amazon).
-
-> Working backwards emerged in 2004: Amazon’s e-commerce strategies had proven successful, and the company was
-> aggressively seeking new opportunities with a large potential market. Where should it look?
->
-> Rather than jumping into developing a plausible product — what an agile mindset might encourage — the company preached
-> going slow to go fast.
->
-> The working backwards approach requires a fully realized vision of a proposed product, embodied in a written press
-> release for the product’s launch. This felt wrong, even unnatural, to software developers and product managers who
-> wanted to get going on coding already.
->
-> The practice has stuck: To this day Amazon works backwards from what it thinks will delight customers, even if it
-> currently lacks the capabilities to make that product. The Kindle e-reader,
-> AWS cloud computing services, and the Echo voice assistant with Alexa all came from working backwards.
-
---- [source][18].
-
-The brilliance of this strategy is that the iterative process of drafting, reviewing, and refining the PR/FAQ documents
-forces the teams and management to take the time to deeply understand not only the problem at hand
-but also the vision of what the product **is** to be, not what the product **might** be
-(when developed with agile MVP principles).
-
-It ensures that everyone involved in the development process, from engineers to marketers, is focused on delivering a
-product that genuinely meets customer needs (which is a core principle in agile,
-but occasionally miss-placed and miss-used).
-
-So, how to "slowly" write the best "working-backwards" solution?
-
-# Worse is better
+# Worse is Better
In 1989, Professor [Richard P. Gabriel][4] wrote an [essay][5] to describe the dynamics of software acceptance.
It is the argument that software quality does not necessarily increase with functionality: that there is
a point where less functionality ("worse") is a preferable option ("better") in terms of practicality and usability.
@@ -157,283 +40,152 @@ In his [essay][5], he sums up the worse-is-better philosophy as:
> be sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness
> if simplicity is retained; especially worthless is consistency of interface.
-This philosophy has been miss-interpreted[^2] (past the catchiness of the phrase), as advocating for doing a bad
-job with code or architecture. In truth, what the philosophy embodies is a stronger emphasis on quality and
-true agile principles (incremental change and sustainable development pace).
-
-To elaborate on "simplicity over correctness":
-
-> Looking through the definition of "Worse Is Better," you might be struck by the immense value it places on
-> correctness, more than most other approaches that state it is a value, but don't support it beyond lip service.
-> The "Worse Is Better" position that "the design must be correct in all observable aspects" is fairly clear on where
-> it stands on correctness. But it is not uncompromising, as the "better to be simple than correct"
-> compromise acknowledges.
->
-> When we state characteristics of a design style, such as simplicity and correctness, these characteristics are
-> often in sympathy, but sometimes they are in tension. How do we resolve that tension? Simplicity is considered
-> the most important characteristic. One consequence of simplicity is improved correctness: not just that it is easier
-> to create correct code, but that it is easier to see that code is correct. As Tony Hoare observed,
-> "There are two ways of constructing a software design: One way is to make it so simple that there are obviously
-> no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies."
-> It is also easier to correct something that is incorrect when it is simple than when it is complicated.
->
-> Furthermore, it is easier to discard and replace something that is simple and incorrect. Because it's simple,
-> we understand it and can replace it with confidence—than something that is complicated and incorrect — because
-> it's complicated, we do not understand it, so replacement evokes fear. There is another side to this as well:
-> favor something that is simple and correct over something that is complicated and correct,
-> because, whatever our aspirations, the latter is less likely to be or to remain correct.
->
-> In short, the (minor) ordering of simplicity over correctness better serves the longer term than just emphasising
-> correctness alone.
-
---- [source][33].
-
-The essence of the philosophy is,
-
-> **when tradeoffs are required in a software system,
-> priority should go to implementation simplicity at the expense of completeness or correctness.**
-
---- [source][8].
-
-This philosophy was observed in the [UNIX philosophy][13]
-- Make it easy to write, test, and run programs.
-- Write programs that do one thing and do it well.
-- Write programs to work together.
-
-And also propagated to many modern languages. For example, [the zen of python][6] emphasizes:
-- Beautiful is better than ugly.
-- Explicit is better than implicit.
-- Simple is better than complex.
-- Complex is better than complicated.
-- If the implementation is hard to explain, it's a bad idea.
-- If the implementation is easy to explain, it may be a good idea.
-
-Now, taking the goals of simplicity then correctness as the highest priorities in the solution,<br>
-So, how to "slowly" write a "working-backwards worse" solution?
-
-# The Big Ball of Mud
-> If you think good architecture is expensive, try bad architecture.
+This philosophy advocates a stronger emphasis on quality and true agile principles through
+"simplicity over correctness"[^1].
+
+It’s easier to maintain simple software, even if it’s not fully feature-complete. A simpler design is often more
+robust because it’s easier to test, easier to debug, and easier to extend later on.
+By aiming for simplicity, you not only make the system easier to work with but also pave the way for future
+improvements.
+# Working Backwards
+Amazon’s "[Working Backwards][21]" process exemplifies the power of taking time upfront to define the
+customer experience. Before any code is written, teams work backward from the final product, crafting
+press releases and FAQs to clarify the vision. This approach forces developers and stakeholders to deeply
+understand the problem before jumping into solutions, preventing the costly mistake of building the wrong thing.
+
+By focusing on the end goal from the start, it ensures that despite that the process may seem counterintuitive
+and slower, it actually speeds up the development and delivers better products.[^2][^6]
+
+# Agile Pitfalls
+Agile, though powerful, is often misunderstood and misinterpreted, Many organizations are taking it too far
+and using it to avoid careful planning and preparation[^3], Many teams focus on velocity and delivering
+a constant stream of features without truly understanding the product’s requirements.
+This "move fast, break things"[^4] approach can lead to shallow products that don’t truly solve the customer’s problems.
+Instead of rushing to build the next feature, teams should balance speed with proper planning, and proper architectural
+decisions, focusing on building sustainable solutions rather than quick fixes.
+
+# Avoid the Big Ball of Mud
In a [paper][10] published in 1997, Authors [Brian Foote][11], and [Joseph Yoder][12]
-examine the most frequently deployed architecture, dubbed "The BIG BALL OF MUD"
-
-> A BIG BALL OF MUD is a casually, even haphazardly,
-> structured system. Its organization, if one can call it that, is dictated more by expediency than design. Yet,
-> its enduring popularity cannot merely be indicative of a general disregard for architecture.
-
-In this paper, the authors examine many of the forces that affect the architecture, including:
-- Time.
-- Experience.
-- Turnover.
-- Skill.
-- Complexity.
-- Change.
-- Cost.
-
-And how these forces can affect the development life-cycles.<br>
-The uniqueness of this paper is that it doesn't describe the resulting systems as anti-patterns.
-
-> These are not anti-patterns, at least in the customary sense. They are not straw men. Instead, they seek to
-> examine the gap between what we preach and what we practice.<br>
-> ...<br>
-> BIG BALL OF MUD might be thought of as an anti-pattern, since our intention is to show how passivity in
-> the face of forces that undermine architecture can lead to a quagmire. However, its undeniable popularity
-> leads to the inexorable conclusion that it is a pattern in its own right. It is certainly a pervasive, recurring
-> solution to the problem of producing a working system in the context of software development. It would
-> seem to be the path of least resistance when one confronts the sorts of forces discussed above.
-
-They go even further as to observe that this specific pattern might have a survival advantage over good code, not a
-position most companies want to be in, since the cost to maintain, and time to fix bugs increases drastically the longer
-the project runs. Moreover, it can (and almost always) lead to the "TOTAL REWRITE" (which is also as expensive -if not
-even more expensive- and takes a lot of time too).
-
-> As per CONWAY’S LAW [Coplien 1995], architects depart in futility, while engineers who have mastered the muddy details
-> of the system they have built in their images prevail. [Foote & Yoder 1997] went so far as to observe that inscrutable
-> code may, in fact, have a survival advantage over good code, by virtue of being difficult to comprehend and change.
-> This advantage can extend to those programmers who can find their ways around such code.
-
-There are always exceptions of course, for example, the paper mentions how the [Wiki-Web code at c2.com][22] has its
-humble origins as a "THROWAWAY CODE" that succeeded beyond the author's expectation, but this is not the rule. The
-observations in the paper, and the prevalence of the "BIG BALL OF MUD" or some dialect of it, can almost always be
-traced back to the previously mentioned forces (Time, Experience, Complexity, ...),
-and how their application always undermines the architecture of the system and results in these undesirable patterns.
-
-Although the publishing of this paper precedes the publishing of the Agile manifesto, it's hard not to see the
-similarities between the common misinterpretation of the Agile principles, and the causes/forces that lead to
-develop big balls of mud.
-
-**A good takeaway from this paper is how important software architecture is to maintaining a healthy system, that
-can be cost-efficiently maintained and relatively fast to fix.**
-
-> It is not our purpose to condemn BIG BALLS OF MUD. Casual architecture is natural during the early
-> stages of a system’s evolution. The reader must surely suspect, however, that our hope is that we can
-> aspire to better. By recognizing the forces and pressures that lead to architectural malaise, and how and
-> when they might be confronted, we hope to set the stage for the emergence of truly durable artifacts that
-> can put architects in dominant positions for years to come. The key is to ensure that the system, its
-> programmers, and, indeed the entire organization, learn about the domain, and the architectural
-> opportunities looming within it, as the system grows and matures.
-
-In other words:
-> Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is
-> discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the
-> offending code, or display a "Not Implemented" message, or substitute dummy data instead. Take some action to prevent
-> further damage and to show that you're on top of the situation.
->
-> We've seen clean, functional systems deteriorate pretty quickly once windows start breaking. There are other factors
-> that can contribute to software rot, and we'll touch on some of them elsewhere, but neglect accelerates the rot faster
-> than any other factor.
-
---- [source][23]
-
-If the architecture is clear (having boundaries) and clean (following design patterns), it's easy-_ish_ to fix the code,
-even if the code is complex or complicated. But if the architecture is not clear or clean, even the most crystal clear
-and clean code will eventually become a big ball of mud, it's the law of entropy.
-
-It is worth mentioning here that, having a design pattern reference guide at arm's length, can go a long way toward
-identifying the design pattern(s) that could be employed to solve different or common programming problems. Personally,
-I keep the refactoring.guru [book][24] (and [website][25]) close by.
-
-So, how to "slowly" write a "working-backwards worse" solution that isn't a "big ball of mud"?
-
-# Re-disposable code
-In a series of blog posts titled:
-1. [Write code that is easy to delete, not easy to extend.][26]
-1. [Write code that’s easy to delete, and easy to debug too.][27]
-1. [Repeat yourself, do more than one thing, and rewrite everything.][28]
-
-The [author][29] suggests that instead of focusing on code reusability, one should focus more on code disposability.
-The reasoning behind this is not that it's just more fun to delete code down the line (although it's really fun), but
-with the main focus on disposability, it results in a system that is actually more reusable, and less tightly coupled.
-
-They start with the following quote:
-> Every line of code is written without reason, maintained out of weakness, and deleted by chance.<br>
-> --- Jean-Paul Sartre’s Programming in ANSI C.
-
-They then give the steps that one can use when developing a disposable system. These steps are summarized in the
-beginning as follows:
-> To write code that’s easy to delete: repeat yourself to avoid creating dependencies, but don’t repeat yourself
-> to manage them. Layer your code too: build simple-to-use APIs out of simpler-to-implement but clumsy-to-use parts.
-> Split your code: isolate the hard-to-write and the likely-to-change parts from the rest of the code, and each other.
-> Don’t hard code every choice, and maybe allow changing a few at runtime.
-> Don’t try to do all of these things at the same time, and maybe don’t write so much code in the first place.
-
-These steps and concepts not only embrace the resulting "balls of mud" and keep them at bay but also utilize the
-resulting effects they have on the system to improve system usability by improving the system disposability.
-> A system where you can delete parts without rewriting others is often called loosely coupled,
-> but it’s a lot easier to explain what one looks like rather than how to build it in the first place.<br>
-> ...<br>
-> A healthy code base doesn’t have to be perfectly modular. The modular bit makes it way more fun to write code,
-> in the same way that Lego bricks are fun because they all fit together. **A healthy code base has some verbosity,
-> some redundancy, and just enough distance between the moving parts so you won’t trap your hands inside.**
->
-> Code that is loosely coupled isn’t necessarily easy-to-delete, but it is much easier to replace,
-> and much easier to change too.
-
-One of the interesting ideas is the discectomy between clean and boring code, and how sometimes clean code
-isn't desirable since it's harder to debug than boring code, or as the author puts it:
-> The problem is that “clean” is highly contextual in meaning. Clean code can be hard-coded into a system,
-> and sometimes a dirty hack can written in a way that’s easy to turn off. Sometimes the code is clean because
-> the filth has been pushed elsewhere. Good code isn’t necessarily clean code.<br>
-> ...<br>
-> Instead of clean, we want boring code where change is obvious.<br>
-> ...<br>
-> It is not to say that clean code is bad, but sometimes the practice of clean coding is more akin to sweeping
-> problems under the rug. Debuggable code isn’t necessarily clean, and code that’s littered with checks
-> or error handling rarely makes for pleasant reading.<br>
-> ...<br>
-> **Code that’s easy to debug is easy to explain.**
-
-Another interesting idea is the misinterpretation of "[Don't Repeat Yourself (DRY)][30]" as "Don't Copy Paste". There
-is a complete post about the misuse of DRY and how it complicates the system design and, in return, makes the system
-less reusable and less disposable.
-
-A healthy level of repetition and redundancy can a lot of times help in maintaining a system that is disposable and
-reusable; the "[Avoid Hasty Abstraction (AHA)][31]" is an example of this.
-
-It can also be seen how these concepts are changing depending on the situation. Sometimes DRY is better than AHA because
-it encapsulates a ball of mud that can be disposable or replaced, yet sometimes AHA is better because [a wrong
-abstraction][32] is even more expensive than no abstraction.
-
-**The bottom line is: There are no silver bullets, use your own judgment.**<br>
-So, how to "slowly" write a "working-backwards boring worse" solution that is a "disposable ball of mud"?
-
-# Slowftware development
-_Pronounced: /sloʊf(t)ˌwɛə/_: is the answer to the previous question by using the previously mentioned concepts to:
-- Work-backwards from the customer's or client's point of view.
-- Identify the right problem that needs to be solved.
-- Simplify that solution.
-- Iterate on the simplified solution with different stakeholders.
-- Start conceptualizing an architecture -based on design patterns if possible-.
-
-Then, once the theorized solution has been decided:
-- Write a disposable boring code, that is also easy to debug (and test).
-- Follow the agile principles, not the agile framework meetings.
-
-Iterate with the customer, once a meaningful chunk of the work has been delivered, and welcome late changes, while
-rewriting your code to be more boring, more disposable, and more testable.
-
-Put simply, use the previously mentioned concepts and techniques, to develop disposable, reusable, sustainable
-software in a truly agile manner -which occasionally can happen in an agile framework-.<br>
-Apply those ideas to make both the development environment and output products better, and more sustainable.<br>
-Make sure that when you are moving, you are moving in the right direction towards a clear goal,
-and not just moving.
-
-This is not a silver bullet to fix current software development, it's not a new paradigm for development, and it's not
-a step-by-step checklist to deliver correct, sustainable, reusable software fast.
-
-This is just the collection of these old ideas, put together in an attempt to make software development more concise and
-more fun, while maintaining a sustainable pace of development with foresight on the end goals, and trying to be as
-fast as possible, without sacrificing or compromising on quality.
-
-So next time, you feel that the way agile is being used in a team or a company isn't working as intended, try suggesting
-or incorporating these ideas in the development process, which I call "slowftware development".
-
-_Special thank to [Abdallah Dorra][34] for proof-reading and making suggestions on unclear sections._
+examine the most frequently deployed architecture, dubbed "The BIG BALL OF MUD":
+> A BIG BALL OF MUD is a casually,
+> even haphazardly, structured system. Its organization, if one can call it that, is dictated more by expediency
+> than design. Yet, its enduring popularity cannot merely be indicative of a general disregard for architecture.
+
+
+"Big Ball of Mud" architectures arise when short-term gains —like meeting deadlines— are prioritized over
+long-term health —like architectural design integrity—. These systems are thrown together hastily, without regard
+to maintainability, leading to increased complexity and either an inevitable need for rewrites or quite high
+maintenance and running costs.
+
+Many reasons could lead to the creation of a "Big Ball of Mud", these include:
+- Time (i.e. meeting deadlines vs time to consider the long-term architectural design and implementation).
+- Experience/Skill (i.e. team experience level, experience with the domain, experience with tools, etc.).
+- Turnover (even with proper handover, some knowledge is forever lost).
+- Complexity (i.e. the domain is complex and bound by certain regulations, like the automotive industry).
+- Cost (i.e. early stage startup that needs to try the quick and dirty solution to validate the idea).
+
+While architecture often takes a back seat to more mundane concerns such as cost, time-to-market, and programmer skill.
+**Architecture is a long-term concern**, and shouldn't be seen as a luxury, or treated with neglect. To quote the
+authors:
+> If you think good architecture is expensive, try bad architecture.<br>
+> --- Brian Foote
+
+Good architecture takes time and meticulous thought, but it pays off when your system is easy to maintain and scale.
+
+# Code Disposability Over Reusability
+Another shift in thinking comes with focusing on code disposability. Rather than trying to write code that’s
+reusable across the board, aim for code that’s easy to delete or replace.
+
+By reducing dependencies and layering the code, you build flexibility into the system, making it easier to evolve.
+"Boring[^7]" (aka simple code) is often more effective than clean but overly abstracted code,
+which is harder to debug or replace when needed.
+
+> Debugging is twice as hard as writing the code in the first place. Therefore,
+> if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.<br>
+> --- Brian W. Kernighan
+
+There can be tension between "Code Disposability" and "Code Reusability", namely around the ["DRY" principle][30],
+In such cases, a "healthy" level of repetition that would make the code more replaceable or removable is preferred to
+making the code more reusable (by being more "DRY").[^5]
+
+# Slowftware Development
+(or slow software development), is the collection of these old ideas and concepts, to develop valuable,
+maintainable software with patience and a deliberate focus on simplicity and correctness.
+
+It's an attempt to embrace working backward from the realized end-product vision, iteration,
+disposable code, and solid architecture design to create systems that don’t just work for today
+but are easy to constantly and sustainably evolve in the future.
+
+Slow software development isn’t about being slow. It is about being thoughtful, sustainable, and ultimately,
+faster in the long run.
---
-[^1]: One example: In a letter to IEEE Computer, Steven Rakitin expressed cynicism about agile software development,
- calling it "yet another attempt to undermine the discipline of software engineering" and translating
- "**working software over comprehensive documentation**" as "we want to spend all our time coding.
- Remember, real programmers don't write documentation."<br>
- This is disputed by proponents of agile software development, who state that developers should write documentation
- if that is the best way to achieve the relevant goals, but that there are often better ways to achieve those goals
- than writing static documentation. [source][17].
-[^2]: one famous misinterpretation, a variation adopted early on by Facebook and attributed to its founder,
- Mark Zuckerberg:
- "Move fast and break things and the idea was if unless you're breaking some stuff, you aren't moving fast enough".<br>
- They used it to build software as quickly as possible, even sacrificing correctness for the sake of a quick release.
+Special thanks to [Abdallah Dorra][34] and [Tom Nick][35] for proofreading, reviewing, and making suggestions on
+this post.
+
+Further Readings:
+- [Write code that is easy to delete, not easy to extend.][26]
+- [Write code that’s easy to delete, and easy to debug too.][27]
+- [Repeat yourself, do more than one thing, and rewrite everything.][28]
+- [Going fast slowly.][3]
+- [Cognitive load.][42]
+
+[^8]: "In our study of 343 businesses (conducted with the Economist Intelligence Unit),
+ the companies that embraced initiatives and chose to go, go, go to try to gain an edge ended up with
+ lower sales and operating profits than those that paused at key moments to make sure they were on the right track.
+ What’s more, the firms that “slowed down to speed up” improved their top and bottom lines,
+ averaging 40% higher sales and 52% higher operating profits over a three-year period." --- [source][40]
+
+[^1]: In this [interview][33], Kevlin Henney elaborates on this claim,
+ "Simplicity is considered the most important characteristic. One consequence of simplicity is improved correctness:
+ not just that it is easier to create correct code, but that it is easier to see that code is correct. It is also
+ easier to correct something that is incorrect when it is simple than when it is complicated. And it is easier to
+ discard and replace something that is simple and incorrect, because it's simple."
+
+[^2]: The Kindle e-reader, AWS cloud computing services, and the Echo voice assistant with Alexa
+ all came from "working backwards" at Amazon.
+
+[^6]: Fun fact: The initial [version][38] of this article was written in an "investigative journalistic" style
+ about the history of the blog's ideas and philosophies, but [Tom Nick][35] suggested "working backwards"
+ from the desired conclusion and end goal of the post, and building the narrative from there,
+ removing all the unnecessary narrative, quotes, and undefended claims. Which led to a better and shorter
+ final version.
+
+[^3]: "The fundamental problem with agile, as many companies use it, is that its relentless pace biases developers.
+ They want to get out a minimum viable product in only a few weeks, so they skimp on scoping out just what the
+ product should accomplish." --- [source][18]
+
+[^4]: Although [Gabriel][4] himself later regretted this statement, many software companies latched onto
+ this particular interpretation of the worse-is-better philosophy. Facebook's Mark Zuckerberg promoted the
+ "Move fast and break things" term. --- [source][8]
+[^7]: "Boring is good. Boring is stable. Boring means being able to focus on your work." -- [source][41]
+[^5]: This claim was inspected by [Sandi Metz][36] in her [blog post][32] and [RailsConf talk][37].
[3]: https://varnish-cache.org/docs/trunk/phk/thatslow.html
[4]: https://en.wikipedia.org/wiki/Richard_P._Gabriel
[5]: https://www.dreamsongs.com/RiseOfWorseIsBetter.html
-[6]: https://peps.python.org/pep-0020/
-[7]: https://lkml.iu.edu/hypermail/linux/kernel/1510.3/02866.html
[8]: https://cs.stanford.edu/people/eroberts/courses/cs181/projects/2010-11/WorseIsBetter/index.php/Worse-is-better.html
-[9]: https://en.wikipedia.org/wiki/Maneuvering_Characteristics_Augmentation_System#Scrutiny
[10]: https://joeyoder.com/PDFs/mud.pdf
[11]: http://www.laputan.org/
[12]: https://joeyoder.com/
-[13]: https://en.wikipedia.org/wiki/Unix_philosophy
-[14]: https://en.wikipedia.org/wiki/Agile_software_development#History
-[15]: https://agilemanifesto.org/
-[16]: https://agilemanifesto.org/principles.html
-[17]: https://en.wikipedia.org/wiki/Agile_software_development#Code_vs._documentation
[18]: https://hbr.org/2021/04/have-we-taken-agile-too-far
[19]: https://www.amazon.com/stores/author/B08FRTFQD8/about
[20]: https://www.amazon.com/stores/author/B08HW23WY6/about
[21]: https://www.amazon.com/Working-Backwards-Insights-Stories-Secrets/dp/1250267595
-[22]: https://wiki.c2.com/
-[23]: https://blog.codinghorror.com/the-broken-window-theory/
-[24]: https://refactoring.guru/design-patterns/book
-[25]: https://refactoring.guru/design-patterns
[26]: https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to
[27]: https://programmingisterrible.com/post/173883533613/code-to-debug
[28]: https://programmingisterrible.com/post/176657481103/repeat-yourself-do-more-than-one-thing-and
-[29]: https://mastodon.social/@tef
[30]: https://en.wikipedia.org/wiki/Don't_repeat_yourself
-[31]: https://en.wikipedia.org/wiki/Don't_repeat_yourself#AHA
[32]: https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction
[33]: https://www.agileconnection.com/interview/worse-better-revisited-interview-kevlin-henney
[34]: https://www.linkedin.com/in/abdallah-dorra-2bbba229/
+[35]: https://tn1ck.com/
+[36]: https://sandimetz.com/about
+[37]: https://www.youtube.com/watch?v=8bZh5LMaSmE
+[38]: https://git.sr.ht/~a14m/a14m.srht.site/tree/9176ade8ff48b3f4d1e538a572bf538c55b480c7/item/content/blog/slowftware-development.md
+[40]: https://hbr.org/2010/05/need-speed-slow-down
+[41]: https://go.dev/blog/compat
+[42]: https://github.com/zakirullin/cognitive-load