I’m researching the influence of working memory in...
# thinking-together
w
I’m researching the influence of working memory in program comprehension. Question for the community: When you’re reading or writing a program, are there specific tasks/examples/etc. where you found it hard to remember things? Maybe you were flipping back and forth between documents, or you kept looking back to the definition of something.
c
It's possible to remember things?
❤️ 2
m
Order of arguments is the worst.
👍 5
i
Does keeping track of the order of operations / events in a complex system (eg: which subsystems are invoked in which order in which circumstances) count? Because that's probably my biggest struggle.
👍 2
e
The biggest improvement that I cite in my beads language design is a 10 to 1 reduction in the number of APIs you had to learn in order to build a product. instead of having 100 drawing functions I have 10 with many parameters, all keyword type of parameters so that through repetition you eventually learn those 10 functions and then you can build your products without consulting any documentation or using auto complete. Autocomplete is a crutch that sometimes covers fir a complex design. It became very popular in the Java world because of the ridiculous number of function names that one ended up with. @Ivan Reese is Correct that the Biggest source of error in programming is trying to make sure things are done in the correct order. That is almost 50% of all programming is sequencing the operations. This is why I used deduction to automatically sequence as much as possible. It is the one thing that prolog had that was not copied by other languages after it. I traced the evolution of languages back to the 70s and there was a big funding battle between two groups one based on prologue in the other based on Lisp. Because the prolog group was based in France they of course lost the Funding battle, And after MIT failed to produce any tangible results from 10 years of high level of funding for automatic programming the term AI was poison for another 10 years after that. It has finally been long enough that people have forgotten the over blown claims of AI and now we are back with an AI fetish. This time however machine learning is delivering some good results and in vision language recognition Some of the areas they’re doing great work and this time it won’t blow up in their face. However as Conway has a proof that consciousness cannot be the result of computation there are Limits to the achievements we are going to get from gradient descent ML
i
Edward — can you also offer an example of somewhere in programming you've found it hard to remember things, specifically? I can't tell if the example of reducing 100 APIs to 10 with many params is about a struggle you've personally faced, or something you've done just to solve an issue others have faced (especially since the rest of your comment drifts way off topic, rather than, say, offering more relevant context). I'm interested in hearing about your personal struggle with remembering, if you have anything to share there.
c
At the moment, I'm having a hard time remembering which files I defined core logic in. I have many entry points due to the complexity of bundling and reusing my own library code. Then, a semi involved multi step build process with WASM in the middle. So, yeah, I'm currently hard at work to reduce that complexity
e
The better your memory the more obtuse you can be in your work And get away with yourself as the reader but will punish any other person who comes along later who tries to understand your code. You can see the bad effects of programmers who have good memories in many examples of code, where variable names are very short and non-descriptive, and where there are excessive numbers of modules with very complex inheritance systems. People with great memories gravitate towards languages which are known to be hard to read but because of their phenomenal memories it does not stress them. Languages where you have to remember exactly how many parameters are being consumed on the stack are highly bifurcated in terms of their user base, because people with poor memories find those languages rough going. Forth and Postscript both require you to know how many operands the function is going to absorb from the stack. That is a tremendous omnipresent memory load. Languages and APIs which have long sequences of required positional parameters in functions also present a heavy burden. In fact almost any function that has more than one positional parameter starts to create a memory burden.. The Lego system proves that it is better to have a small number of primitives that are repeated many times then to have a huge set of complicated pieces to connect together.
w
@Ivan Reese can you elaborate? What’s the higher level task that requires you to understand the order of operations? (debugging, performance optimization, etc.)
Also, for APIs I think Matplotlib vs. Seaborn is a great example of what @Edward de Jong / Beads Project is talking about. MPL gives 100s of knobs each with its own API function. Seaborn gives maybe a dozen top-level functions with many parameters, along with many smart defaults.
🧠 1
i
My OoO difficulty usually occurs when acclimatizing myself to a new codebase, needing to learn what all the pieces are and how they fit together. Alternatively, returning to a familiar codebase after a time away from it, needing to recall or reacquaint myself with the workings. Debugging too, sure, but I think that has less to do with memory and more to do with visibility. The period of honing-in on the cause of a bug (subjectively) feels more like following a scent than making a map. Once the cause is found, it's usually a methodical process to determine the root cause. Optimization is almost the opposite of learning / reacquainting — by the time I'm ready to do optimization, I will have loaded the entire program into my head, so to speak (or at least the relevant bits), so it's all in working memory and is easy to recall.
💯 1
w
In what cases do you need to understand OoO to understand a codebase? Perhaps put another way: for what kinds of pieces do you need OoO to reason about their composition? For example, if I’m understanding how Seaborn draws a graph, it might choose to draw the axis labels before the data points, but that’s an arbitrary choice. Understanding the OoO doesn’t give insight to the system design.
i
One example would be a video game, full of subsystems that all operate with different notions of time — networking code working in terms of packets with variable ping, physics locked at 60hz, gameplay logic happening at various rates (some stuff is every frame, some stuff is once every few frames, some stuff goes into a low-priority queue, some stuff happens at specific moments), rendering synced to the display refresh interval, audio happening both in sync with the gameplay logic but also at the audio sampling rate, and on and on. These subsystems are kinda isolated, but they're also kinda interdependent. There could be a lot of shared state, or a lot of dynamism in how these subsystems affect one another, or a lot of design decisions that prioritize performance at all costs. Ultimately, the code needs to be quite deterministic and very well understood in order to ensure that the game runs quickly and correctly, and you don't (can't?) have automated tests or static verification, so you generally have to work on it by loading it all into your head. (I hope I'm understanding your question correctly. Sorry if this is not what you had in mind.)
w
@Ivan Reese that helps, thanks for elaborating. I think what I’m getting at is — what is a specific task involving this kind of understanding? e.g. a hypothetical task is “I need to understand how many ms elapse from the start of the tick to when my gameplay logic runs”, which requires understanding OoO/subsystem dependencies, presumably. I’m being a little pedantic here because understanding how to provide cognitive support has to start with a task. e.g. when evaluating whether to use a bar chart vs. pie chart to display some data, you don’t ask “which is better”, you ask “which is better when a person is trying to find the maximum value in my dataset”. Here’s a high-level task taxonomy from “Program Comprehension During Software Maintenance and Evolution”. These are a bit vague, but a useful starting point.
i
One case where I find my memory really taxed is, broadly, "picking up where I left off". If I have a half-implemented feature from a past work session, especially if that feature is a replacement for an existing feature, I often don't quite remember which places I've updated to support the new feature and which ones I haven't. So I need to try to recall what things have been updated, while scouring the codebase for places that still need to be updated. I think that falls under "adaptive code changes", but I might be misunderstanding.