Lady’s Computer: MY computer over YOUR internets

Lady’s Weblog

Programming Resolutions for 2024

Lady

Published: .

The following are a set of resolutions for the upcoming year which I think are important to ensure that the output of the work that I do is humane, use·ful, and generally in·line with my ethical and esthetic sensibilities. (I some·times use the spelling prrgrrmmng to distinguish programming of this form from other kinds.) Many of them stand in sharp contrast to current trends within computing, and the resolutions would hardly be meaningful otherwise.

It is also worth noting that many of these are things that I am already doing, but I’m recording them here in the hopes that others might find them use·ful as well.

Resolution ①: Commit to Unix Philosophy

This resolution comes first because it is foundational to the approach I take with software projects. Different people have different understandings of what “Unix philosophy” means, so I want to be clear about it here :⁠—

  1. Programs should be scoped as tightly as possible; they should do as few things as possible while still providing the necessary flexibility for complex operations.

  2. Programs should read from stdin and write to stdout. How this happens may be adjusted with commandline flags, but the vast majority of information should be provided in‐band through stdin/stdout/stderr and not through some other mechanism.

  3. The input and output of programs should follow common conventions and standards, so that both are easy for other programs to replicate and process.

  4. Programs should be built to combine with other programs in ways that significantly increase their potential.

  5. Programs which aren’t broken should not be fixed. Instead, new programs should be written which provide missing features.

What Unix philosophy brings to the table, to my eye, is really a different mindset around dependency management. In contemporary programming, dependency management is typically thought of in terms of Semver‐versioned package sources and a package manager which resolves them appropriately. These packages are then included in the project which makes use of them.

Under the Unix philosophy, in contrast, dependencies come not in the form of packages but a·p·i’s. This means :⁠—

  • The burden is on users to provide programs which support the necessary a·p·i’s, but in contrast, any program which supports the necessary a·p·i’s can be used (e·g Free·B·S·D or F·S·F).

  • Dependencies are replace·able piece·meal as new versions come along, and conversely, dependencies which “just work” can remain in place for years.

  • Newer programs and implementations can be easily turned into a replacement for older programs and implementations by just applying appropriate transforms on the input and output (and, potentially, vice·versa).

  • Instead of needing to manage one dependency tree for programs written in Ruby and another for programs written in Swift, the same dependency can be used in all applications across languages, because all languages provide the ability to read from stdin and write to stdout.

I don’t want to criticize package managers too harshly, but I don’t think that language‐specific package managers are a good solution for personal computing, and I don’t think learning five different a·p·i’s across five different programming languages is helping any·one. People writing personal scripts or doing highly‐individualized computing cannot afford to constantly be interfacing with package managers to ensure that every one of the dependencies for every one of their scripts is up·to·date. Make small, reliable programs with common interfaces that any·one can use, and depend on existing a·p·i’s with multiple implementations, not strictly‐versioned, single‐language packages where possible.

Resolution ②: Commit, Also, to the Web

The Unix philosophy works well for programs being run on one’s own personal computer, but it doesn’t necessarily map well to networked technologies over the internet. For these, thankfully, we have the philosophy of the Web :⁠—

  1. The Web is a network of resources, named via global identifiers and accessible via U·R·L’s.

    • The global identifiers should have the form of I·R·I’s and, ideally, should be persistent and unique across space and time.

    • U·R·L’s and I·R·I’s should be human‐readable and transcribable, but should not encode unnecessary information or information which is liable to change.

    • U·R·L’s should not change unnecessarily. When they do change, having separate, persistent identifiers helps to rediscover the resource at its new location.

  2. Resources should be retrievable in common formats using common protocols.

    • Common formats include H·T·M·L, X·M·L, and Json. Specialized forms of resource may allow other formats, for example N·Triples or Turtle for metadata resources, in line with community practice.

    • Plain, stateless H·T·T·P(·S) requests should be used to access resources when·ever possible.

  3. Resources should be designed in a way so as to maximize their utility to the person accessing it. They should be readable and processable without any specialized tools. They should conform to community standards for information representation.

  4. Resources should link to other, related resources by U·R·L. Put together, linking, common formats and protocols, and U·R·L’s provide a similar level of functionality to that of reading and writing from standard input in Unix. They enable the creation of complex user‐agents which operate by processing and combining a number of simpler resources.

Follow web philosophy whenever publishing documents or data. This is often the easiest, and most boring, solution to online publishing. Be boring. Shift the focus from making interesting protocols to making interesting tools which use those protocols.

Resolution ③: Write for the Future

If what was popular in technology never changed, it would mean that technology culture had reached a stale·mate, which would probably be a bad thing. Instead, assume that what is popular today may not be popular tomorrow. This probably means that popularity is not actually a very good indicator of which technology a person should use, unless that person is very committed to redoing all of their work every five‐or‐so years.

Popular technologies change, but old data remains, and if one wants that data to remain accessible and useful, that means one needs to construct it in such a way so as to not break in the absence of the current technological fads. Use formats which can be analysed with tools that are proven to be durable, and converted from there to more contemporary formats as necessary. Write programs which can be run in the absence of current technological infrastructure, for example specific iterations of a particular package manager or versioning scheme.

If everything new eventually becomes old, then in five years it will not matter whether a program was written using new technologies or not. However, what will matter is whether the program still runs and is useful. Use that perspective as a baseline when making decisions regarding program architecture and a·p·i. Contemporary problems will persist for as long as there is contemporaneous data, so build solutions for contemporary problems and contemporary data which can persist alongside them.

Resolution ④: Capture the Current Moment

A good program might remain useful for many years. That makes programs, in a sense, transmitters of history (a fact which any·one who has ever read the phrase for historical reasons knows well). How·ever, programs rarely bother to encode their social history alongside the technical.

I think this is a loss of radical potential, but also a loss of a chance to invest in programs as a site of human connection and understanding. For all of history, humans have decorated the tools they use with symbols and meaning; tools are in fact, generally, an important part of material culture. But despite this, computer tools have typically only been decorated in the most banal of ways (branding). The internals of programs (their structures, variable names, source code comments) could be records of much more than just a dry series of technical decisions—if we were willing to invest in them as social objects and not merely objects of science.

Don’t write “timeless” programs, write programs which can be understood in any time because they encode the human particularities of living in the world in the year and place in which they were written. View programs as instances of instrumental culture which not only might be decorated (the same as one might carve an image into a bench, or embroider a picture onto a pillow) but whose very construction is social (akin to choosing fabric patterns and designs for a quilt). Recognize these aspects of programs as not merely “esthetic”, but also conveyors of historical, cultural, or political meaning; endow them with symbols accordingly.

Resolution ⑤: Compute Less, Transform More

There are times when computers actually need to do computing. But much of the time, computers are used simply to access and present data. If data is accessible in form $A and simply needs to be presented in form $B, this is a problem of data transformation not a problem of computing per·se.

Json is a good data structure for accessing information for computing but it is a bad data structure for accessing information with the intent to transform it into something human‐readable. X·M·L and s·expressions, on the other hand, are trivially transformable, and X·M·L in particular is home to a variety of human‐friendly destination formats. Consequenty, for data which is intended for human consumption, use X·M·L, or use a language with a straightforward transformation into X·M·L. Do not use bespoke Json syntaxes which require specialized tools to process or display. Do not use abbreviated, context‐specific formats which are easily separated from the contexts needed to interpret them correctly.

Assume all data is intended for human consumption because all programs should be written by humans and for the benefit of humans. Always have a plan for formatting data in a human‐readable manner.

Resolution ⑥: Collaborate Socially or Not at All

Much of the current open‐source tech world is currently focused on the problem of how to drop the social barrier for software collaboration to be as low as possible. Personally, I think that asocial collaboration leads to asocial software. And in my experience, typically these sorts of “open” projects are in fact entirely closed to ideas and contributions which do not align with their pre·existing agendas, because there is no social structure by which needs can be negotiated or meaningful pressure applied.

Require social interaction for collaboration with one’s software. Make it clear from the outset who is responsible for addressing public concerns, and require that the public address that person or those people specifically. Have communication channels for frequent collaborators, and put those channels in a place where those collaborators feel welcome and able to contribute. Have an onramp for interested persons to get more involved; invite people who give a shit to give a shit formally.

Don’t use faceless ticketing platforms where strangers shout into the void in the hopes that some·one with power will see their post and agree. Don’t erase power differences between maintainers, leads, collaborators, and the general public. Stop participating in spaces which don’t know how to manage their communities or don’t perceive themselves as having communities to manage. Make a hard exit when projects respond to suggestions only with opinions, and never questions.

Conclusion

Obviously, the resolutions in this post are probably impossible to fully implement with every program I work on or every line of code I make—especially when those programs or code are being written within constraints set by somebody else. However, I think they are a useful aspiration and yardstick against which to measure the things I make. These yardsticks are use·ful, of course, as people who make things and want to make things better. If you also write computer programs, I’d be interested in hearing how yours compare.