10

The golden rule of software quality

 3 years ago
source link: http://www.haskellforall.com/2020/07/the-golden-rule-of-software-quality.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

This post summarizes a rule of thumb that I commonly cite in software quality discussions, so that I can link to my own post to save time. I have taken to calling this the “golden rule of software quality” because the rule is succinct and generalizable.

The golden rule is:

Prefer to push fixes upstream instead of working around problems downstream

… and I’ll explain implications of this rule for a few software engineering tradeoffs (using examples from the Haskell community and ecosystem).

Disclaimer: The golden rule of software quality bears no relationship to the golden rule of treating others as you want to be treated.

Third-party dependencies

Most developers rely on third-party dependencies or tools for their projects, but the same developers rarely give thought to fixing or improving that same third-party code. Instead, they tend to succumb to the bystander effect , meaning that the more widely used a project, the more a person assumes that some other developer will take care of any problems for them. Consequently, these same developers tend to work around problems in widely used tools.

For example, for the longest time Haskell did not support a “dot” syntax for accessing record fields, something that the community worked around downstream through a variety of packages (including lens ) to simulate an approximation of dot syntax within the language. This approach had some upsides (accessors were first class), but several downsides such as poor type inference, poor error messages, and lack of editor support for field completions. Only recently did Neil Mitchell and Shayne Fletcher upstream this feature directly into the language via the RecordDotSyntax proposal , solving the root of the problem.

The golden rule of software quality implies that you should prefer to directly improve the tools and packages that you depend on (“push fixes upstream”) instead of hacking around the problem locally (“working around problems downstream”). These sorts of upstream improvements can be made directly to:

  • Your editor / IDE
  • Your command-line shell
  • Programming languages you use
  • Packages that you depend on

Note that this is not always possible (especially if upstream is hostile to outside contributions), but don’t give up before at least trying to do so.

Typed APIs

Function types can also follow this same precept. For example, there are two ways that one can assign a “safe” (total) type to the head function for obtaining the first value in a list.

The first approach pushes error handling downstream:

-- Return the first value wrapped in a `Just` if present, `Nothing` otherwise
head :: [a] -> Maybe a

… and the second approach pushes the requirements upstream:

-- Return the first value of a list, which never fails if the list is `NonEmpty`
head :: NonEmpty a -> a

The golden rule states that you should prefer the latter type signature for head (that requires a NonEmpty input) since this type pushes the fix upstream by not allowing the user to supply an empty list in the first place. More generally, if you take this rule to its logical conclusion you end up making illegal states unrepresentable .

Contrast this with the former type signature for head that works around a potentially empty list by returning a Maybe . This type promotes catching errors later in the process, which reduces quality since we don’t fail as quickly as we should. You can improve quality by failing fast at the true upstream root of the problem instead of debugging indirect downstream symptoms of the problem.

Social divisions

I’m a firm believer in Conway’s Law , which says:

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.
— Melvin E. Conway

… which I sometimes paraphrase as “social divisions lead to technical divisions”.

If social issues are upstream of technical issues, the golden rule implies that we should prefer fixing root causes (social friction) instead of attempting to mask social disagreements with technical solutions.

The classic example of this within the Haskell community is the cabal vs. stack divide, which originated out of an interpersonal conflict between Michael Snoyman and Herbert Valerio Riedel . The failure to resolve the upstream social friction led to an attempt to work around the problem downstream with a technical solution by creating a parallel install tool. This in turn fragmented the Haskell community, leading to a poor and confusing experience for first-time users.

That’s not to imply that the social dispute could have been resolved (maybe their personal differences were irreconcilable), but the example still illustrates the marked impact on quality of failing to fix issues at the source.

Conclusion

Carefully note that the golden rule of software quality does not mandate that you have to fix problems upstream. The rule advises that you should prefer to upstream fixes, all other things equal. Sometimes other considerations can prevent one from doing so (such as limitations on time or money). However, when quality is paramount then you should strive to observe the rule!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK