DEV Community

Cover image for Start by writing messy code
Srikanth
Srikanth

Posted on • Originally published at svemaraju.github.io

Start by writing messy code

The conventional wisdom in software engineering advocates for breaking down code into loosely coupled functions, classes, and modules, among other things. Numerous books and blog posts discuss various approaches that help us achieve the best possible design for our code.

Sometimes, we may get lucky and find a design pattern that perfectly matches our business logic. However, there's a risk of making premature assumptions, which can result in our code being misaligned with the business problem.

I propose an alternate approach that may sound counterintuitive.

Start by writing messy code—-messy code that diverges from the traditional "clean" code, following design patterns, programming paradigms, or any opinionated design methodologies.

What do I mean by messy code here?

I begin by putting all my code in a single function (or method). This means disregarding principles like Separation of Concerns, Single Responsibility Principle, or even DRY (Don't Repeat Yourself).

Then, I write tests to verify that my code works.

At this point, I am technically ready to open a Pull Request, meaning somebody will need to read my code and review it. This is when I check my code for readability.

Based on my experience, having as much context available in one place makes code more readable. When I have a function with all the code in it, I have all the context I need to inform my design. If I feel the code is unreadable, I break the large function into meaningful blocks. On the contrary, figuring out the building blocks from scratch would take me much longer.

Having all the code in one place can be considered messy, but it is much more malleable than having code implemented in mismatched design pattern.

What about working with existing codebase?

An existing codebase may have predefined patterns. But that doesn't mean they should be unchangeable. As described above, these patterns may be a perfect fit. In that case we use them to inform the design of new features. But if they aren't, there is no reason why we should stick to them for all future code.

If all future implementation is dictated by initial design decisions, then it means that our software is hard to change. Software is supposed to be "soft" i.e. easy to change, and change is a good indicator of a healthy and successful software project.

How did I arrive here?

My fascination with architectural patterns and design methodologies began early in my career. Initially, I felt embarrassed by my code, which worked perfectly but lacked the elegance of a well-designed system. To address this, I immersed myself in studying design patterns, only to later realize that many of these patterns were primarily designed for Object-Oriented Programming. As I continued to develop my coding skills in Python, a more flexible language, I learned the importance of seeking design patterns native to Python.

Over time, I also encountered counterarguments such as WET (Write Everything Twice) versus DRY (Don't Repeat Yourself), which expanded my perspective on coding.

Given the abundance of strongly worded literature in the software industry, it is easy to become too fixated on the means of accomplishing our tasks and lose sight of our ultimate goals. Therefore, I find it valuable to approach coding from a first principles perspective—breaking down a problem into its fundamental elements and rebuilding a solution from those elements. Starting with messy code represents my personal approach to this philosophy, and I encourage you to find your unique path in coding as well.

If you liked reading this post, you can follow me on LinkedIn for more.

Cover Photo by Peter Olexa on Unsplash

Top comments (21)

Collapse
 
aarone4 profile image
Aaron Reese

+1
Make it work
Then make it fast
Then make it pretty

As for WET. Totally agree. Write it once. If you have to write it again, grit your teeth and JFDI. The third time indicates this is a common pattern and needs to be abstracted.

Collapse
 
thedenisnikulin profile image
Denis

pretty and fast are commonly two conflicting characteristics, so I'd suggest writing pretty and only if it's not fast enough, try to make it work fast

Collapse
 
aarone4 profile image
Aaron Reese

It depends on how you define pretty. I agree that it is probably not a good idea to abuse some esoteric language feature for speed (e.g. falsey values in JavaScript) as speed of understanding is more important than speed of execution on most cases.
To me, pretty means following the conventions of your language or organisation (PEP8 if writing python), using SOLID, use proper names for variables, functions and files, lay your code out consistently (e.g. either use semi colons or don't use them in js but don't mix them)
Anything you can do to reduce cognitive load without actually changing the logic is always worth the time invested.

Collapse
 
dimitrim profile image
Dimitri Mostrey

You forgot the KISS principle 😁

The only person that has to understand the code is the coder. If I open a piece of code written years ago, it often goes like "OMG, I wrote this? What a mess!"

A problem can be solved in many different ways. We usually chose the path that feels comfortable. In knowledge and habit.

Beautiful written code becomes a habit in itself. Isn't that's true for everything we do? From cooking to gardening, painting and finetuning a car engine. And coding.

It's a beautiful satisfying hobby. Thanks for the thoughts @svemaraju

Collapse
 
aruku profile image
Eduardo

The only person that has to understand the code is the coder.

I agree with pretty much the entire article, but this line above is only true if you are 101% sure that nobody else is ever going to get involved in that project.
In the vast majority of cases, more than one person works on a codebase simultaneously, and you never know what might happen in the future.
Everybody has to understand the code, now and later.

Collapse
 
svemaraju profile image
Srikanth

Beautiful written code becomes a habit in itself.
I definitely agree with that! Thanks for the comment.

Collapse
 
freddyhm profile image
Freddy Hidalgo-Monchez

My approach to code (but problem solving in general):

1) get my ideas out as quick as possible to accomplish my goal (docs, code, drawings, etc.)
2) refactor lightly (just enough for it to be coherent lol)
3) get feedback

Rinse and repeat.

That's why I find the Test Driven Development model super helpful. The first step is to write a test that fails, then make it pass as quickly as possible, then refactor. I believe the less cognitive load you have at each step, the more you can focus and deliver effectively.

Aiming for perfection on the first go all alone is crazy paralyzing, and unless you're a mind reader, is often so terribly wrong.

Good code to me is best created through a collaborative, iterative effort, between you and your team.

Collapse
 
ccarcaci profile image
ccarcaci

I'm overall agree with your point.

Just one thing is not convincing me:

At this point, I am technically ready to open a Pull Request, meaning somebody will need to read my code and review it. This is when I check my code for readability.

This means VERY long reviews of the code that will results in:

  • obsolescence of the MR code
  • high costs in terms of time spent by other developers doing review
  • each MR could potentially bring new design decisions. IMO it's OK changing design decisions overtime, it's not OK changing them without involving all and without identifying the parts of the legacy code to update

WDYT?

Collapse
 
svemaraju profile image
Srikanth

Absolutely @ccarcaci . I am totally in favor of submitting the best version of the code for the PR. But the only reason I worded it like that is some times it is okay to keep the code as it is. It is not always an unmanageable mess.
Software development is a team game so I am definitely with you on involving your team to come up with design changes.
Thanks for reading and taking the time to comment your opinion!

Collapse
 
not-ethan profile image
Ethan

I somewhat agree with this. I like the concept of it but I think some stuff should be moved into its own functions, classes etc in the same file just so you can easly come back the next day and still know what you wrote and dont need to spend an hour figuring it out.

Collapse
 
noriller profile image
Bruno Noriller

You had me until the opening PR part.

For me it's normal to make "messy" code, but usually, I clean up a little before commiting it, then as I "finish" the PR I'm planning, I will clean it further.

As you finish whatever you're doing, then you would have a great view on where to extract something to a function or maybe you feel something might work, but is still messy.

People are not in my mind, so the only thing they will see is a mess. Similarly, as time passes I'll forget the finer details. Not only that, a long and messy something means you have to keep track of a lot of things... in other words, you're ignoring a lot of things because of the "magical 7 ± 2" people can keep in their "ram".

Collapse
 
svemaraju profile image
Srikanth

No, I am with you there. The reason I worded it like that is because readability is subjective. Sometimes I have seen people preferring code to be in design patterns they are familiar with. It is more readable for them. Sometimes it is the opposite. What I wanted to articulate here, and of course this is relative AF, is that sometimes it is okay to keep the code as it is. It is not always an unmanageable mess. But yes, if it is not up to your standard, then by all means clean it up. 🙌
Thanks for checking my post and taking the time to comment your opinion!

Collapse
 
darty profile image
samsepi0l

But what about people who name variables with some short letter that doesn't make sense at first, just to check if that function is gonna work before writing some long beautiful thoughtful name for the variable.
I do it all the time when I'm unsure if something won't work and things are complex. I just name variables and functions as short as possible just to discern while trying to make it work, and if it does work, then I prettify those names to be thoughtful so when I come back I know what I'm reading.

Collapse
 
svemaraju profile image
Srikanth

I just want to get the code working as quick as possible and then invest time in making it readable and performant. :)

Collapse
 
cjsmocjsmo profile image
Charlie J Smotherman
  1. Brain dump.
  2. Make it work.
  3. Make it fast. (time is money)
  4. Make it pretty (if it makes sense, after all time is money)

Happy Coding

Collapse
 
codingtheself profile image
Alex Miller

It's a very natural approach for me ever since I am coding.

  • Writing everything inside one function
  • using very short single characters variable names
  • See if it works step by step

Later when I push it to repo I clean it a bit.

Collapse
 
darty profile image
samsepi0l • Edited

I clean it a bit

Or you forget to clean it and leave it as is, to do some other stuff.
And it becomes interns job to fix it :D hahah

Collapse
 
ralphsebastian profile image
Ralph Sebastian

We all had humble beginning. It was never clear and lean in the start, we have to begin with baby steps, the learn how to walk and run (metaphorically for coding, of course).

Great tips, hopes your experience and tips can help more people.

Collapse
 
akashpattnaik profile image
Akash Pattnaik

Pretty well said!

Collapse
 
darkterminal profile image
Imam Ali Mustofa

Hmmm.... interesting

Some comments may only be visible to logged-in visitors. Sign in to view all comments.