48 ms·
I feel there's a beautiful representation of (many) problems that is waiting to be found that makes particular software problems easy to read and understand. Wh
by samsquire 3y ago
I feel there's a beautiful representation of (many) problems that is waiting to be found that makes particular software problems easy to read and understand. When the mental model of the software just makes sense. I don't want to reject other people's models of how programs work but I want to understand them.
Unfortunately, I feel the the original problem can be obfuscated by adding ideas to the existing problem who now need to understand your ideas (or mental model) of the problem to understand your code. I need to understand how you think to read your code. And if your way of thinking is more advanced than mine or incomplete or not great, then my work is harder.
Mental models are how I understand software, there is what I call a "critical insight" that makes the code obvious and easy to understand. I don't want to be deciphering and spend days investigating code to understand how to change it or build upon it or use it. I want the APIs to reflect their expected usage and behaviours.
My perspective is that computers are adding and arrangement machines - they add and do operation on numbers and move things around to different locations. My mental model of computers is that it comes down to LOGISTICS and arrangement/ordering problems. Unfortunately, APIs and data structures are nested and ordered and obfuscate the underlying movement of things between places or addition to different things.
Everything that obfuscates the rules of the computation means getting the behaviour you want from the code is harder.
I've often thought about "commutative computation" where we specify what we want to be true to the computer and the computer works out how to arrange all its existing computations to satisfy that additional invariant. I often think of software as a series of behaviours rather than functional or imperative.
Think of a materialised view, we have an existing behaviour of the computer and we want to customise the behaviour. You could work out where you need to insert your code snippet into but that's really hard. Or you could add an invariant to the system that the system now satisfies.
- kqr 3y ago> Unfortunately, I feel the the original problem can be obfuscated by adding ideas to the existing problem who now need to understand your ideas (or mental model) of the problem to understand your code. What do you think are the steps someone goes through when they obfuscate the problem by adding ideas? Like why do you think they do it?
- samsquire 3y agoI can tell you what I want to believe of myself that I think I do. I try think of the simplest most elegant, beautiful solution to the problem that allows the minimal of code and minimal cleverness and complexity be used to solve the problem with trivial loop, map, hash lookup or traversal or association. That usually comes with trying to see the problem in a different light, to reframe the problem as a different kind of problem, which can obfuscate the original problem.
- gbear0 3y agoThings get obfuscated because someone's viewing the problems from a different abstraction lens, and they're building a system onto that lens. Eg. Iterate through an array: const arr = [1, 2, 3]; for (let i = 0, l = arr.length; i < l; ++i) { console.log(arr[i]) } Let's model it differently using an iterator: const arr = [1, 2, 3]; const arrIter = arr[Symbol.iterator](); let i = arrIter.next(); while (!i.done) { console.log(i.value); i = arrIter.next(); } At this level it's still pretty obvious what's going on, but you can still see that there's a level of abstraction between an array access vs calling 'next/value', and that obfuscates what is actually happening at the computation/instruction level. If I extend this another level then I'm going to start modelling problems using an iterable and not an array/index. New requirements come in and we extend to use an async iterable. Everything still works nicely, but in some scenarios where the actual iterable is just an array, now there's a lot of extra overhead to just do an index lookup. Using the iterator allows the code to be reused in more scenarios, but there's usually a cost to switching the lens of abstraction so that it fits into a problems modeled differently.