Personally I think the most important thing to minimizing code complexity is ensuring that it understandably maps to the business logic. The business logic is the essential complexity and everything else can be seen as waste. The first step is getting the lexicon right. Frequently the business lexicon is ambiguous in such a pervasive way that the people immersed in the business aren't aware of the discrepancies. For…
Code doesn’t have to be a mess
131–140 of 190 posts
Re: Code doesn’t have to be a mess
#132Earlier quoted context omitted.
> I find single file dense leetcode style code easier to understand and follow the flow. Algorithmic code I can reason around. A large mature codebase is far harder to get to know. I genuinely can't tell if you're being serious or not. If you are, do you also like to read books written as one giant chapter? Or entire chapters as one giant paragraph?
The book analogy you use isn't very accurate. Even if you merge chapters and paragraphs like that, you still read it sequentially. Just in a less comfortable way. Which is not at all like a modern codebase that is modular, abstracted, etc. If you're new to a codebase, and want to understand one particular feature, you'd likely need to jump back and forth across 10 files. It's not far-fetched to say that makes it diff…
Let's say you have a simple endpoint that takes a list of comma separated inputs, parses them as numbers and spits back a sorted version of that.
I don't want to see a version of that, which a compiler might have inlined. Including the implementation of the sorting algorithm. I only want to see a high level of abstraction version of it. Basically just something like (pseudo code in a non existent language) :
fun endpoint(input):
inputs[] = split(input, ',')
numbers[] = parseAsIntegers(inputs)
return quicksort(numbers)
I can easily understand what this does and what the idea is behind this "algorithm" in 3 lines. If I had the "inlined" version of this I would have to manually identify each of these parts and potentially skip over tens to hundreds of lines.I think this is really a bit about trust. Do you trust that these named functions I am calling do what their name does? Does quicksort actually do a quicksort or has someone implemented bubble sort in there? Of course this is a minimal example and especially quicksort would probavly just be a library but imagine all of these were large complex pieces of our code base.
Personally I am an advocate for using functions (methods or whatever your language calls them etc) and naming them properly and then trusting those names by default. I want to spend time making this nice and understandable and abstracted once when writing. Not every time someone reads it. As soon as something does not seem to behave in the way the name suggests I will then and only then go check the actual implementation and for example find out that parseAsIntegers actually also supports floats and quicksort is not actually quicksort but bubblesort and that is why this endpoint was slow etc.
Re: Code doesn’t have to be a mess
#133In my experience people refactor code to their own understanding of the problem and not all refactorings improve the code. People abstract before an abstraction is necessary. I find single file dense leetcode style code easier to understand and follow the flow. Algorithmic code I can reason around. A large mature codebase is far harder to get to know. One of the first things I do when I study a new codebase is find a…
Is it deliberate that your comment itself is like an instance of the methodology you describe? Small separate stand-alone thoughts vs. a well-understood description (harder to write, to consume) in longer form commentary? That's not a criticism at all by the way, I just found it striking.
In hindsight if you focus on three questions: is it good? Is it right? Is it true? You'll head toward a good direction
Synthesis of ideas is really important and the building blocks of understanding are fascinating. Programming and mathematics is taught as building blocks and then deliberate practice.
I really enjoy reading plain descriptions of things, especially of other people's code.
If you understand the core insight, difficult things can be easier to understand and apply for you.
I really want to understand how tracing compilers work and LuaJIT, JVM and V8 but I found the code a bit too hard to understand as I jumped into the wrong locations.
There has been two instances where Wikipedia was enough for me to understand and write an algorithm that implemented the description. Wikipedia doesn't have pseudocode for multiversion concurrency control but it does have an accurate if subtle description. I did the same for btrees but I did read some other people's implementations to get a feel. I of course wrote mine completely differently.
I want people to document their code enough so that the core principles or idea behind their code could be reimplemented by someone else just by reading the description of how it works.
Rpython and Pypy documentation is good but I still don't understand it enough to implement what it does. Which means I'm missing some detail or core insight.
Re: Code doesn’t have to be a mess
#134Obviously we don't want a complete dumpster fire of a codebase, but some mess is inevitable and healthy. First see the mess, then refactor. Refactoring before the mess is how you end up with crappy abstractions.
In the past few years I've adopted the attitude that code cleanliness isn't really that big of a deal. There are some obvious guidelines to follow around readability, encapsulation, etc., but these days I care more about system architecture than I do the code itself. Localized code is easy to change/refactor/clean up, the system itself is not.
Re: Code doesn’t have to be a mess
#135Earlier quoted context omitted.
Maybe I'm weird but a lot of my refactoring actually concretizes overly abstract code. It's easier to think about adding functionality to a block of code when you acknowledge that at the moment it only does 2 things, rather than using obscure wishy-washy language that implies it could do a dozen things. Where I'm definitely weird is that I have a higher verbal score than your typical developer, and I'm not afraid to…
I had to look up "telegraph" to confirm I'd understood you correctly. I don't recall seeing it used in the context of describing language, so I doubted my interpretation. I've heard it used most in discussions of boxing: a boxer's posture or their sequence of muscle activations _telegraph_ their planned attack such that their opponent has time to block or counter. I like the way you used it. I'll try to use that myse…
Re: Code doesn’t have to be a mess
#136I think this is terrific advice. Over decades I have compiled my own list which contains all these and bunch of other behaviours that are needed for successful project. I would add one or two very important thing missing from the list. One, not explicitly mentioned but covered in other points is to plan for simplicity . Make simplicity an explicit goal of the project and set up process to remind of it at various impo…
Thanks for your comments, this is helpful. I especially like your point about planning for simplicity and making it an explicit design coal. Communicating this clearly to the team seems super important. As for adding things out of intellectual gratification: This is so true. I've seen this all too often, myself included. Many good engineers are curious by nature, and it can be tough to restrict this curiosity. Maybe…
The job of the most experienced person in the software development organisation should be to spot unnecessary complexities and find ways to eliminate them.
The issue is, most experienced people tend to be engaged in activities for political reasons like adding new technology -- which tends to be perceived as more valuable than removing it.
I might be biased (by selection). I am called upon to join and help projects that face significant problems (emergencies all the time, no time to breathe, way behind schedules, unable to deliver anything, etc.) But every time I join a project like that, the repairing process tends to start with removing stuff rather than adding. And if stuff needs to be added this is usually so that it makes possible to remove much, much more of complexity somewhere.
As an example, we have stabilised at least 3 projects by removing "microservices" and rolling everything to a single monolithic application. Not saying microservices is a wrong idea, but saying it might be wrong for a particular project without strong automation culture, tooling and without large enough problem to solve. Somehow this always starts with strong opposition and ends with happy people that can code and not spend significant portion of their time dealing with complex, flaky infrastructure.
My rule as I present it to the team is "I want at most one of anything unless we understand exactly why we need more than one." So one programming language (unless you need one for backend and one for frontend, then we need two), one application (unless you have multiple teams and then one per team might be better to make them independent), one repository, one cloud infrastructure provider (AWS tries to be on parity with GCP, why do you need something from GCP just for it being incrementally better?), one place to store all documentation and procedures, one database tech (do you really need half of the application use MongoDB and another half use Postgres?), etc.
The rule might sound childish, but it is simple and helps people make better decisions on their own which is essentially what you as a tech lead want.
Re: Code doesn’t have to be a mess
#137In my experience people refactor code to their own understanding of the problem and not all refactorings improve the code. People abstract before an abstraction is necessary. I find single file dense leetcode style code easier to understand and follow the flow. Algorithmic code I can reason around. A large mature codebase is far harder to get to know. One of the first things I do when I study a new codebase is find a…
> I tend to write reference implementations of everything, then combine them together as a separate project.
Re: Code doesn’t have to be a mess
#138In my experience people refactor code to their own understanding of the problem and not all refactorings improve the code. People abstract before an abstraction is necessary. I find single file dense leetcode style code easier to understand and follow the flow. Algorithmic code I can reason around. A large mature codebase is far harder to get to know. One of the first things I do when I study a new codebase is find a…
Re: Code doesn’t have to be a mess
#139Changing code that works, even if it’s a rock you ought to put down, is a risk.
Re: Code doesn’t have to be a mess
#140Earlier quoted context omitted.
I had to look up "telegraph" to confirm I'd understood you correctly. I don't recall seeing it used in the context of describing language, so I doubted my interpretation. I've heard it used most in discussions of boxing: a boxer's posture or their sequence of muscle activations _telegraph_ their planned attack such that their opponent has time to block or counter. I like the way you used it. I'll try to use that myse…
It means communicating something quite clearly but by indirect means (and possibly inadvertently).
Them (on the subject of 4 new methods): hey why did you make method 3 look "weird"? You should make it look like the other three.
Me: because one of these methods can set the building on fire, and the rest can't. I bet you can guess which one is the dangerous one. Works as expected.