Confession, I don’t really know software engineering. I’m not a SWE, have never had a SWE job, and the codebases I deal with are likely far less complex than what the average SWE deals with. I’ve tried to get good at it in the past, with partial success. There are all sorts of SWE practices which people recommend, some of which I adopt, and some of which I suspect are cargo culting (these two categories have nonzero overlap).
In the end I don’t really know SWE well enough to tell what practices are good. But I think I do know a thing or two about writing notes. So what does writing notes tell me about good practices for writing code?
A good note is relatively self-contained, atomic, and has an appropriate handle. The analogous meaning when coding is that a function should have a single responsibility and a good function name. Satisfying these properties makes both notes and code more readable (by yourself in the future).
This philosophy also emphasizes the “good enough” principle. Writing only needs to be long enough to get a certain point across. Being concise is preferred to being verbose. Similarly, code only needs to have enough functionality to satisfy some intended use case. In other words, YAGNI. For this reason, complex abstractions are usually unnecessary, and sometimes actively bad (because they lock you in to assumptions which you later have to break). Furthermore they take time and effort to refactor.
The ‘structure’ of code (beyond individual files) is rather arbitrary. People have all sorts of ways to organise their collections of notes into folders. I will argue that organising by purpose is a good rule of thumb; in research contexts this can look like organising code according to which experiments they help support (or common code kept in utilities). With modern IDE’s it’s fairly simple to refactor structure at any point, so it’s also not necessary to over-plan it at the outset. A good structure will likely emerge at some point.
All this assumes that your code is personal, i.e. primarily meant for your own consumption. When code needs to be read and written by many different people it becomes important to have norms which are enforced. I.e SWE exists for a reason and has legitimate value.
However, I will argue that most people (researchers included) never enter that regime. Furthermore, ‘good’ SWE is a skill that takes effort and deliberate practice to nurture, benefiting a lot from feedback by senior SWEs. In the absence of being able to learn from those people, adopting practices designed for many-person teams is likely to hinder productivity.
Programs must be written for people to read, and only incidentally for machines to execute.
There is a difference if the code is “write, run once, and forget” or something that needs to be maintained and extended. Maybe researchers mostly write the “run once” code, where the best practices are less important.
Yeah. I definitely find myself mostly in the “run once” regime. Though for stuff I reuse a lot, I usually invest the effort to make nice frameworks / libraries
Writing code is like writing notes
Confession, I don’t really know software engineering. I’m not a SWE, have never had a SWE job, and the codebases I deal with are likely far less complex than what the average SWE deals with. I’ve tried to get good at it in the past, with partial success. There are all sorts of SWE practices which people recommend, some of which I adopt, and some of which I suspect are cargo culting (these two categories have nonzero overlap).
In the end I don’t really know SWE well enough to tell what practices are good. But I think I do know a thing or two about writing notes. So what does writing notes tell me about good practices for writing code?
A good note is relatively self-contained, atomic, and has an appropriate handle. The analogous meaning when coding is that a function should have a single responsibility and a good function name. Satisfying these properties makes both notes and code more readable (by yourself in the future).
This philosophy also emphasizes the “good enough” principle. Writing only needs to be long enough to get a certain point across. Being concise is preferred to being verbose. Similarly, code only needs to have enough functionality to satisfy some intended use case. In other words, YAGNI. For this reason, complex abstractions are usually unnecessary, and sometimes actively bad (because they lock you in to assumptions which you later have to break). Furthermore they take time and effort to refactor.
The ‘structure’ of code (beyond individual files) is rather arbitrary. People have all sorts of ways to organise their collections of notes into folders. I will argue that organising by purpose is a good rule of thumb; in research contexts this can look like organising code according to which experiments they help support (or common code kept in
utilities). With modern IDE’s it’s fairly simple to refactor structure at any point, so it’s also not necessary to over-plan it at the outset. A good structure will likely emerge at some point.All this assumes that your code is personal, i.e. primarily meant for your own consumption. When code needs to be read and written by many different people it becomes important to have norms which are enforced. I.e SWE exists for a reason and has legitimate value.
However, I will argue that most people (researchers included) never enter that regime. Furthermore, ‘good’ SWE is a skill that takes effort and deliberate practice to nurture, benefiting a lot from feedback by senior SWEs. In the absence of being able to learn from those people, adopting practices designed for many-person teams is likely to hinder productivity.
Quoting Dijkstra:
Also, Harold Abelson:
There is a difference if the code is “write, run once, and forget” or something that needs to be maintained and extended. Maybe researchers mostly write the “run once” code, where the best practices are less important.
Yeah. I definitely find myself mostly in the “run once” regime. Though for stuff I reuse a lot, I usually invest the effort to make nice frameworks / libraries