Get off Your Horse and Stop Coding like a Cowboy

Most teams try their best to follow “best practices.” The way I think about best practices is:

The stuff that is generally accepted as a good idea in the long run, even if it is a bit of a pain to implement in the short run.

Seasoned developers love so-called “best practices” – not because they’re smarter or better than less experienced developers – but because they have personally been burnt multiple times by the consequences of the often-times “easier” way to go.

This is the part that rang the most true for me. I've been burnt plenty of times by doing things the "easy" way rather than the best way.
 
I'm definitely guilty of being a cowboy.

Especially regarding the unit testing part
 
Refactor mania

The part that probably irritates me the most when working with teams that take a notion like "clean code" to the silly farm -- it's only done when it's refactored past its cognitive demise.

For those relatively newer to programming i.e. the OOP / structured programming generation is where everything is perfect because it's structured with objects and stuff. Sorry but you'd be wrong to believe the problem of spaghetti code disappeared when when OOP started.

I've seen and worked with far too many teams who take pride in their ability to refactor their code down to a "golden ratio" of 3/4 lines per function, and they think this is something to boast about. Pssst.. Today's OOP spaghetti code is now called Ravioli code.

i.e. “The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.” -- following this BS too spiritually serves only to introduce a high cognitive overhead, basically it turns simple linear stories into a tangled collection of functions and classes without any consideration for the value that clear task progression makes in tackling maintenance or enhancements.

TL;DR; An example is always worth far more than endless blah blah.
This Swift article represents this to a T: the irrationality of chasing line counts.
https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5#.k2ejgs7ua

Swift (Apple's new language) has a number of features to tear down the pyramid of doom:
  1. Facilitating early exits with a new type of asserts called guards, similarly embedded functions and lambda variables not only meet the need to segment code to avoid duplication, ..., but also to logically group task progression in a single area.
  2. side benefit is that these inline functions and lambdas stay hidden from the API i.e. clean APIs are a direct consequence of better structure, not so with the previous penchant for chasing line counts.
 
Last edited:
It's amazing how much cleaner one's OOP code becomes when you realize that sometimes a struct is just a struct and a function is just a function...

My overriding design philosophy is to keep things as simple as possible. A great coder is someone who can construct the simplest possible expression of a necessarily complex solution.
 
"Clean code is easy to read. Therefore code that is easy to read is clean."
"Always ask yourself 'Is this really the correct name/place for this?'"

If you take those onboard, you will write better code. Unfortunately you get people who have no right to, still autopilotting

This of course doesn't mean tiny functions and classes everywhere.
 
Fighting language constructs put in to improve clarity is senseless (example link I provided); yet so too anyone attempting to create an entire program in a single class and/or view controller. Simple acid test: if you need to jump between a number of functions, classes & files to understand code, you've likely pushed it too far. Example: you definetly know it's a f..k up when you've got 18000 classes in app.

The phrase I like to keep in mind is: "Brevity is very important, but Clarity always trumps Brevity. ... when in doubt, never sacrifice Clarity just to achieve Brevity."
 
Last edited:
I'm quite pedantic when I code but working for a demanding client with an aggressive cloning strategy involving out-of-sync instances have taught me the value of being able to shoot from the hip while herding cattle.
 
When all else fails, the cowboys are called.

[video=youtube;AFa1-kciCb4]https://www.youtube.com/watch?v=AFa1-kciCb4[/video]
 
I'm quite pedantic when I code but working for a demanding client with an aggressive cloning strategy involving out-of-sync instances have taught me the value of being able to shoot from the hip while herding cattle.

Yip there's always one of those; I prefer to skip and pass it to the "clean coder" crew.
Analogy that those accustomed to a lot of shyte are best equipped to add to it.
 
6 shooter from the hip when the shyte's that wide that you can't miss.
 
[)roi(];16818701 said:
... This Swift article represents this to a T: the irrationality of chasing line counts.
https://medium.com/swift-programming/why-swift-guard-should-be-avoided-484cfc2603c5#.k2ejgs7ua
Picking up from my rant, here's an article that responds the above and expresses succinctly why this is a bad idea:
http://owensd.io/2016/01/04/re-why-swift-should-be-avoided.html

I'd even go so far to say: you'll know you're a rubbish programmer when the code you produce is cognitively overbearing for other programmers; bad refactoring is far worse than unindented code.
 
Wow, this is a really nice article. Loved reading every bit of it. It makes developing software within an organization sound fun :)
 
Last edited:
The rule I use for limiting complexity is that functions should not need more than 30 seconds to understand.
 
The rule I use for limiting complexity is that functions should not need more than 30 seconds to understand.
I really don't maintain any hard and fast rules, flexibility is required depending on what you're working with, for example:

A single pixel filter without the process loop i.e. only a specific formula to manipulate the color components could easily run between 8 to 30+ lines; separating this into more functions only detracts from process steps & increases cognitive stress. More complex algorithms like pixel dithering, blur or median filters can easily get substantially more bloated.

Similarly I've built parsers, tokenizers and compression algorithms where sub parts can easily run up 40 or 50 lines; splitting this makes no practical sense in process comprehension., as there is no reuse, and many small functions or objects will only further complicate the understanding of something that is already very complex to begin with.

Note: the counting of this is based on code typically formatted to 80 character width, including all asserts and preconditions (quite a few which are multi-line)

Yes these are specific areas of complexity, most functions fall within 6 to 7 lines, but I mentioned this as it serves to challenge the notion that a fixed set of rules can be practical.

Anyway I mentioned in the Swift thread that I'd most probably post something about refactoring: i.e. what Swift offers to streamline code as part of a refactor; if I have the time I'll try to include a few before and after scenarios: the single pixel image filters (binary, grayscale, tint, color shading, ...) are probably great examples. Alternative would be to tackle pixel dithering; if there's any interest let me know which you prefer.

Btw I picked these two areas re you encounter many different algorithms, some more complex than others; and jointly they have parts that can be simplified to reduce duplication and improve the overall API.

At least with code examples it'll be easier to discuss / challenge my view.
 
Cowboy coding illustrated.

Real OOP.jpg
It's always starts off looking like a great idea...
 
Top
Sign up to the MyBroadband newsletter
X