
Your code may be elegant, but mine works - mendicantB
http://omniti.com/seeds/your-code-may-be-elegant
======
freyrs3
Reducing software development practices down to these cute catchphrases is a
bit disingenuous. If you're writing throwaway code for a client with loose
constraints and a tight deadline you'll write code differently then you would
when you expect to maintain a long term relationship with a client who expects
a high degree of correctness. I'm tired of these trite articles espousing some
cute mantra holds as if it's some universal property of software development.

~~~
danellis
The worse thing is that he's saying "you shouldn't spend extra time to do the
right thing", and then tries to justify that by giving examples of people
doing the wrong thing. Nobody is calling spending weeks writing a caching
layer for a 20-row database "elegant" or "best practice". That's a complete
straw man.

~~~
logicallee
I don't know. The whole ecosystem we live in (YC) seems to be about, "Your
idea may be good, but mine exists."

Basically, the same thing as he's saying.

~~~
cloverich
Sort of. That just means they endorse an Agile approach - ship bare minimum
features early, and continuously improve. Not ship bare minimum features
early, and who cares about how its designed. The whole over-engineering
argument _is_ a straw man, because over-engineering is just as bad as under-
engineering. Neither one is desirable in professionally written software.

------
candybar
The main reason that I agree with this is that developers are, as a group, the
boy who cried wolf. It's not that technical debt doesn't matter or code
quality doesn't matter but so many developers complain about technical debt
and code quality when their concern is irrelevant or flat-out wrong that it's
difficult to distinguish a legitimate concern from complete BS.

Developers very often use technical debt or doing the right thing or similar
arguments as an excuse not to understand an existing codebase and past
choices, to convince management or fellow developers to rewrite something that
doesn't need to be rewritten, or to buy time to learn and try new
technologies/methodologies/patterns that are supposed to be better without
understanding tradeoffs or to satiate their desire to overengineer and build a
cathedral, when a simple cart would suffice. These efforts acrrue, rather than
pay off, actual technical debt. A simple hardcoded one-off is a lot easier to
throw away or fix than a half-assed "elegant" design with configuration
options and tight coupling everywhere.

All this means developers and managers are correct to be skeptical when
another developer talks about technical debt as a reason that they can't do
something quickly. It's not that elegance and technical debt and doing the
right thing, etc, don't matter.

~~~
leobelle
I don't know man. I have been buried under mountains of technical debt before.
It's a pretty horrifying experience and makes me paranoid about writing bad
code. It's kind of like how starvation makes you see food differently.
Technical debt isn't a joke.

------
RyanZAG
I managed to read the article before it went down, it was a pretty good read.
Hopefully it comes back up soon.

Anyway it makes a good point that business objectives come before "best
practices" which I agree with, but you need to be careful when cutting corners
that you don't actually sabotage your business objectives. The real discussion
is actually on a risk level: if I cut corner X, I can potentially make revenue
Y unless cutting corner X causes a problem and I incur loss Z. Cutting that
corner is only good if

    
    
      P(no problems | cutting corner X) * Y > P (problems | cutting corner X) * Z
    

If this equation looks tough, it's because it is tough. This is not an easy
decision and you really need to be on top of your game to choose correctly.
Alternatively, Y must be much bigger than Z and you have some faith in your
shortcut. But for most dev work, a lot of the time you're going to be getting
that equation wrong if you just guess it and it's why so many experienced devs
will tell you not to cut corners.

~~~
fennecfoxen
It's also worth noting that he's talking about things like "if your client
needs a Christmas promotion and you deliver on Dec 29". This sounds about
right. But if you're in a time-sensitive situation and your code will only be
used for a brief period of time, your business needs are probably very
different than a code-and-maintain-forever situation (e.g. a SaaS offering).

I am currently developing and maintaining a system which powers an ongoing
core business process. If it goes down, employees basically sit around unable
to accomplish work. I hope that this system will be robust enough to continue
operating for years, maybe decades, and anticipate that during that time four
or five business units will either transition their processes to this system,
or create new processes that use this system. Clean, quality, well-tested and
extensible code clearly matter here in a way that they don't for a one-off
Christmas 2013 promotion.

~~~
Edmond
> But if you're in a time-sensitive situation and your code will only be used
> for a brief period of time, your business needs are probably very different
> than a code-and-maintain-forever situation (e.g. a SaaS offering).

I think this captures the central problem in our current software development
state of affairs. Because as developers we are stuck with primitive tools that
make doing even trivial stuff time consuming, we have been conditioned to view
every piece of code we write as a "will be maintained forever" proposition.
You don't generally see people using excel and worrying about the
maintainability of their spreadsheets, because even sophisticated spreadsheets
are trivial to create and so the default mentality is use and throwaway.

This is a problem we are trying to tackle at my startup, a web developer tool
that you can use to quickly put out applications to support day-to-day
operations without obsessing about whether you're going to need to build a
spaceship out of your current requirement.

~~~
the_af
I don't know that sophisticated spreadsheets are trivial to create. I've seen
way too many weird, buggy and outright broken spreadsheets to believe that.

I agree with you we should strive to make trivial things simple to write, and
I also agree many programming tools fail at that, but I don't agree the
software we write (in general) qualifies as trivial. Even some spreadsheets
don't qualify. People writing them often make a horrible mess of it, unless
they truly are simple spreadsheets.

~~~
arthurjj
As bad as the spread sheets can get it's helpful to have the business side
make them. Even if you do have to implement a 'real' solution at least you now
have a prototype to go off of

------
romaniv
_If the project is late, it 's not done. Period._

Bullshit. Most deadlines in software engineering are fake. There are some that
aren't, but they are exceptions, not a rule. If you're writing all your code
as if every deadline is the Judgment Day, you're doing software engineering
wrong and not making the right trade-offs.

The unfortunate reality is that there are some engineers who will gladly
deliver software 5% faster and 600% worse just because it makes them look good
with the management. They justify their behavior by all kinds of BS, but in
the end it hurts the industry, their clients and the society at large.

(There is another breed of engineers that will deliver software 600% slower
and 200% worse because of overcomplicated design. Yeah, that's also a
pathology. But it's not like you have to choose only between these two
pathologies.)

~~~
jarrett
Exactly. The author cites a Christmas promotion as an example. Yes, those
types of projects exist, but in my experience, they're a tiny minority. Almost
every deadline I've ever faced was set artificially. The developers estimate
how long the project will take, they negotiate with management, and one or
more deadlines are established. Often these deadlines are missed (not due to
the programmers, BTW), and there's no actual harm to the company or the
project.

In my view, the reasons for such artificial deadlines are a) so all involved
parties can plan their schedules, and b) because an _undefined_ timeline has a
tendency to become an _infinite_ timeline. Rarely do these two needs imply
dire consequences for a missed deadline (provided it's not missed by an
excessive duration).

~~~
jmccree
You are lucky if deadlines with actual penalties have been a "tiny minority"
of your experiences. The problem I experienced too much at some companies is
"management" making artificial deadlines become real deadlines. VP of X sees
feature set for delivery on Friday, sets up demo for potential client on
Friday. Now everyone is in crunch mode or the company suffers when client
can't see the feature. Or CxO drops in and says "I got invited to Conf Z in
two weeks, I told them I'm going to demo Feature C and they just tweeted it,
that's still on track, right?" Now, those were not the best managed companies,
but I'd imagine there's a lot of people who end up in similar situations. As
well, the author works at a consulting company, where I imagine many of the
deadlines are baked into the contracts as deliverables with financial
penalties for not meeting them. Consulting is a different world than a startup
where you get to build something you hope to personally use for years.

~~~
jarrett
Ouch! Yes, that can happen, and I'd argue it's pathological. Let me rephrase
that series of events as follows:

1\. Artificial deadline is set. 2\. Artificial deadline is unnecessarily
converted into crucial deadline. 3\. Code quality suffers, saddling the
company with technical debt that costs real money and real opportunities
later.

> many of the deadlines are baked into the contracts as deliverables

Oh absolutely. I'm a consultant too, and I do that all the time. I set my
contractual deadlines such that I don't have to sacrifice the codebase.
Granted, there are exceptions to every rule, and I'm not going to claim I've
_never, ever_ accrued technical debt due to a deadline. But I wouldn't make it
a philosophy, which the article seems to be doing.

------
viraptor
He presents so many false choices it's not even funny. (also we're adults,
either you really want to fucking write it, or don't - stars don't help)

> If the client needs a Christmas promotion, and you deliver the best product
> in the history of promotions -- on December 29th -- it's worthless.

There's almost always another option - if it's going to be a complete mess
that will give everyone additional work in January, then maybe the scope needs
to be cut and the remaining features polished.

Even if the code is completed, it can be worthless (or worse):

\- if it crashes your whole site for all users, rather than just the promotion
part

\- if it exposes security issues

\- if it not only fails on edge cases on the day, but wakes up your on-call
people and spoils their christmas with work

> And taking it a step further, a veteran programmer should know when and,
> most importantly, how to cut corners, if needed, to meet the deadline. Which
> brings me to my next point: over-engineering.

It must be great to work at a company that only has fully aware veteran
programmers that never make mistakes when cutting corners. It's a shame
there's no recruitment link.

> This way, though you may be accruing technical debt, you are also accruing
> revenue immediately, and you can reconcile the debt over time.

A couple of paragraphs before he talked about limiting scope actually. Yet,
we're back to the only balance most people talk about - time and money
(expected revenue from change). I've seen something different everywhere. You
talk about technical debt, you plan to get rid of it, then another big idea
comes and you add more technical debt to get the shiny feature out. Getting
rid of technical debt happens years later when people simply cannot live with
the issues - they turned from annoyance that takes you 5 minutes to workaround
into company-wide issues that block releases for days.

He's also ignoring the fact that the technical debt is cummulative - every
time you do something quickly you add a couple more minutes to the every
following time you need to work on the same code. Sure - it may allow to get
_this_ feature out quicker, but it will also _force_ you to cut corners on the
next feature - because you don't have the abstractions you need available.

I'm tempted to assume that the author never really had to deal with the issues
someone else left in the code, because they also thought they're veteran
programmers and know where to cut corners.

~~~
ryanjshaw
Well this _is_ a developer working on Christmas promotions. It's a bit
difficult to take him seriously. Let's see how he copes on a smallish 20,000+
person hour project scope with a 5 year+ expected maintenance lifetime and
then revisit the discussion.

------
Draiken
The code is elegant AND it works, so it'll beat the one that just works every
time.

This kind of post is always the same, but any decent developer knows when you
have to just "get it done" and when you should take time to make it the right
way. And of course, that dirty code will be refactored later on.

Always using the "f __*ing works " strategy just means you're mediocre at
writing code. Either because you led the management team to think anything can
magically be built in a "hackathon" or you just don't care about what you
build.

~~~
otterley
> And of course, that dirty code will be refactored later on.

In my experience, the same product development lifecycles and business
priorities that led to the dirty code in the first place will cause it to live
forever. Code that works doesn't tend to get refactored unless it needs to be
revisited for some other business purpose.

~~~
Draiken
I partially agree... normally this is a symptom of someone selling it as being
something super simple to do for the managers.

Personally I make it clear to them that if they need something impossibly
fast, I'll need to come back for it later or it will cost us in the long run.
When you do that, it's their choice to leave crappy code there, and later on
you can point that out, when you need double the time to change that crappy
little piece of code.

But I've seen managers (that should know better) that just take the fastest
path always and just don't care, unfortunately it happens :(

------
MrZongle2
My code might not be that elegant, but it's _maintainable_.

I've followed "hey, it works" developers who knocked out functionality
quickly. Their by-product was Lovecraftian code.

~~~
frenchy
This is a far better metric. Elegance, while a worthwhile goal, is at its best
a vague notion and at its worst, a guise for all sorts of leaky abstractions.

~~~
courtf
I adore elegance, but over time have come to understand that edge cases tend
to creep into those "leaky abstractions," and you can find yourself unraveling
things, at least partially, in order to solve bugs.

There's no shame in this IMHO, and lots of very good programmers have to add
inelegant shims to solve specific edge cases. I enjoyed reading this article
(previously linked on HN by another) which I think has some relevance here:
[http://www.gigamonkeys.com/code-reading/](http://www.gigamonkeys.com/code-
reading/)

------
j_baker
Your code may f'ing work, but my code works _and_ is elegant. So what if my
code takes a little bit longer to write? From a technical perspective, it's
easy to see how this is good. Spending a little bit of time to make your code
better will save you hours if not days in the long run.

I also have to question whether this is really good from a business
perspective. "First mover advantage" really is overrated. Rather than cutting
corners to launch your product a couple of days sooner, perhaps you should be
focusing on the long term.

Granted, there are all kinds of caveats we can think of. For example, very
early startups don't have the option to focus on the long term and just need
to ship something. But even then, putting in a little bit of time up front to
polish your code will greatly help your velocity for your next couple of
features. You are planning on having more features past the first couple,
right?

------
raganwald
_Something important is almost never mentioned in all the literature about
programming and software development, and as a result we sometimes
misunderstand each other._

 _You 're a software developer. Me too. But we may not have the same goals and
requirements. In fact there are several different worlds of software
development, and different rules apply to different worlds._

[http://www.joelonsoftware.com/articles/FiveWorlds.html](http://www.joelonsoftware.com/articles/FiveWorlds.html)

~~~
tjr
Similarly, paraphrasing (as I don't have my copy right here with me),

Not all software projects are the same, no more than all construction projects
are the same. You can quickly nail a dog house together with only vague
planning and minimal craftsmanship. But if you want to build a house for
people, you have to plan more, pay more attention to what you're doing, and
make sure the result meets the local codes. If you want to build a skyscraper,
you have to put even more work into planning, robust engineering, and code-
meeting than you do with a house.

[http://www.amazon.com/Software-Architecture-Primer-John-
Reek...](http://www.amazon.com/Software-Architecture-Primer-John-
Reekie/dp/0646458418/)

I've worked on software for iPhones and on software for jumbo jets. The two
activities almost aren't even the same thing. Drawing on other life
experiences, I might liken it to jazz improvisation vs. classical performance,
or to mobile phone snapshots vs. professional portraiture. Overlapping, yet
different enough that methods which work for one do not necessarily make sense
for the other.

~~~
raganwald
Exactly. But it doesn't degeneralize to "Everything is so different that rules
of thumb are not useful guidelines," but rather that within a particular
"genre" or "world," there are sensible defaults that don't work in other
genres or worlds.

------
whyme
Great article.

Note that much of the attitude comes from a belief that what is good for the
company is ultimately good for the engineer.

However, I'll suggest that's not always the case. Take for example one of the
OA's reflections:

" _Technical debt should be weighted against the actual ROI, because in many
cases it is more cost effective to launch early. This way, though you may be
accruing technical debt, you are also accruing revenue immediately, and you
can reconcile the debt over time._ "

Unfortunately, dependant upon your company, that last part may never happen
and if I were to frequently experience that at a company, well, you better
believe I would rather quit and if I couldn't quit I still would rather put my
foot down and pump the tech debt argument for all it's worth, otherwise, in
the longer term, working there would be a living hell.

I know I'll get a lot of flak for this take, but all I can say is that while
I've quit companies like that, I understand why some people couldn't do the
same, and at that point it may require some tough love people management in
effort to create a brighter future with a healthy work place.

~~~
vinceguidry
> Unfortunately, dependant upon your company, that last part may never happen
> and if I were to frequently experience that at a company, well, you better
> believe I would rather quit and if I couldn't quit I still would rather put
> my foot down and pump the tech debt argument for all it's worth, otherwise,
> in the longer term, working there would be a living hell.

Wish I could upvote you twice.

My company has so much technical debt in the system that we have five people
doing the job of three. Technical debt is almost never paid and the result is
invariably a big-ass mess.

You might then ask, "well if the company's profitable then what's the effing
problem, then?" The answer is that there's a ginormous difference between
where they _could_ be and where they are now.

I'm slowly coming to understand that broken is normal. Paying off technical
debt can cause your company to mutate superpowers simply because _nobody else
does it_.

~~~
chris_mahan
Perhaps the concept of Technical Bankruptcy should be introduced.

------
tdumitrescu
"This way, though you may be accruing technical debt, you are also accruing
revenue immediately, and you can reconcile the debt over time."

The last part of that statement is troubling, because it happens so rarely. I
think a lot of devs want to lean towards more engineering "up-front" because
they've been smacked repeatedly with the business reality that the first
version of that code is what you're going to be stuck working with, and
building on top of, for a long time.

~~~
antimagic
Yes. "Reconciling technical debt" does not fit in well with the philosphy of
the title. Why refactor when you can just write more code that "fucking
works".

Of course, those of us with a bit more experience know that a badly designed
module can very easily get enmeshed in a system, with the whole system being
designed with the bad module's deficiencies being taken into account. Now you
don't just have to refactor the bad module, but all of the code around it too,
which turns out to be a difficult ask, so nobody does it, and the bad code
becomes locked in.

As always, the higher up the software stack you work, the easier it is to
justify bad code, but when you are providing infrastructure code, that will be
used by applications, you had better be sure that your interfaces are clean,
and your implementation stable. Try pushing some inelegant code to the Linux
kernel, and you won't enjoy to the experience...

------
buckbova
As a database architect I disapprove of this message.

Nearly everything is revisited and changed at some point over the life of the
product. If the initial design is a hack or not well thought out, the change
will likewise be uglier than the original code.

Even worse, if the original code is not understood by the next developer, it
will be thrown out and rewritten.

Take the extra time in the early stages to design, think about fault
tolerance, possible future enhancements, extensibility, robustness,
reusability, etc. It will pay off.

Yes I over engineer nearly everything I design and yes my deadlines are met.
With an elegant design, it is often easier to make late changes on a project.
If you follow understood design patterns other people can jump into a project
and pick it up right away.

------
lostcolony
I live by a comment Joe Armstrong made on this (from Erlang and OTP in
Action):

"Make it work, then make it beautiful, then if you really, really have to,
make it fast."

(The quote continues "90 percent of the time, if you make it beautiful, it
will already be fast. So really, just make it beautiful!")

~~~
bnegreve
> _90 percent of the time, if you make it beautiful, it will already be fast._

In fact, I disagree with this. The reason is that "elegant" usually means
"decoupled" whereas many optimizations actually consists in "recoupling" to
take advantage of special cases or to share resources among various decoupled
objects.

Designing software to be fast _and_ elegant is actually quite challenging
problem. Of course, that makes it even more interesting.

~~~
lostcolony
I would argue that the reason you are choosing to recouple things, is because
you fall into that 10%. Most problems can and should be solved first
correctly, second elegantly, and you will find at that stage it is "fast
enough". It's so rare to not find that to be true, overall (i.e., some
industries, such as high speed trading, there is no such thing as fast enough,
but they're writing < 10% of the total amount of code being written), that
yes, I'd say the quote is accurate, and the exceptions fall into that 10%.

Interestingly, too, you indicate "recoupling". That is, to couple again.
Meaning for you to even be in this situation, realizing what you need to do,
you had to first make it elegant. Otherwise you'd be optimizing...what,
exactly? You have no metric.

------
badman_ting
Hmm. It's not that I disagree as such, but more that people who talk like this
tend to be terrible cowboy coders. But I agree that developers can be
annoyingly fussy about things that actually do not matter at all. No argument
there.

Plus elegance is often a bullshit notion and when people say it what they
really mean is "what I personally like".

------
nateabele
I used to work at OmniTI. The real irony of this article is that it was
written by a guy who's (in)famous for his indecipherable Perl one-liners.

I think that's about all that needs to be said.

~~~
kyberias
> I think that's about all that needs to be said.

Yeah, and that's like a perfect definition for "ad hominem" argument.

~~~
nateabele
You people really need to work on your fallacies. Quoting from the Wikipedia
definition of _Ad hominem_ :

"[I]n which a claim or argument is rejected on the basis of _some irrelevant
fact about the author_ [...]"

Leon is a really nice, super funny guy, but the fact that no one can maintain
the code he writes is _highly_ relevant to the subject of the article. In
summary, [http://lwtc247.files.wordpress.com/2010/06/get-a-brain-
moran...](http://lwtc247.files.wordpress.com/2010/06/get-a-brain-morans.jpg)

~~~
kyberias
Exactly. I claim that someone's personal opinion on the author's coding skills
IS irrelevant. We should concentrate on his _arguments_, not dismiss his
arguments based on here-say about what he has or hasn't done.

He doesn't argue that HE writes good code, he discusses general topics.

------
programminggeek
This is a great excuse to write terrible code that "works" until it goes out
and breaks. Then it doesn't work because you saved a little bit of time by
cutting corners.

What is the cost of it breaking? $0? $1,000? $10,000?

What is the cost to fix the broken code?

What is the cost to maintain it?

How much developer time do you waste down the line because they have to fix
the "working" code?

I say these things because I've seen this attitude expressed in a large
codebase and it sucks a lot to work with and has wasted many hours of
developers' lives.

Technical debt is almost never paid back. Just know that going in to whatever
you are building.

~~~
mrweasel
>How much developer time do you waste down the line because they have to fix
the "working" code?

That is absolutely spot on. One of the hardest thing is explaining to
management that the code your co-worker wrote in a "flash" three years ago is
still eating up developer time today. We have a few ill-conceived or badly
written systems that seems to eat up time and constantly interfere with new
projects. The problems are pretty much invisible to management, because the
developers spend a few hours here and there proppring up the badly written
systems. Over time you end up having to spend all your time just putting out
fires rather than helping the business moving forward.

~~~
randomflavor
O-TI makes money fixing broken shit.

------
gamerdonkey
I'm honestly sorry I gave that a pageview.

It's an article chock full of caveats ( _Best practices vary wildly across the
board, except for the ones any decent programmer obviously knows._ ), straw-
men ( _Someone spending a week to implement caching on a 20-row table probably
wasn 't crafting elegant code anyway._), and contrived anecdotal examples (
_Christmas apps must be out by Christmas. My God, what a breakthrough. Most
projects are not nearly this straightforward._ ).

------
Ologn
> "You hate testing!"

I started working as a Unix sysadmin in 1996, and while I have always written
programs, and have been doing so more heavily lately, I never wrote a program
with someone else before. All of my programming has either been programs
completely written by me, or small patches sent to existing open source
projects. The purpose of testing aside from the most rudimentary always eluded
me.

A few months ago I wrote my first program along with a good, professional
programmer. I would code, he would code, I would code. He was good, but I
noticed some of his changes would break my code. It occurred to me that
testing is something of a communication device. I create functionality, I
implement the test, then I tell other commiters to run the test suite before
commiting code. If the tests do not complete, they know their code will break
functionality I made.

I guess this is obvious, but when I read top reasons to do TDD etc. it is
usually not mentioned as a prominent reason to do testing, if it is mentioned
at all. I do not find tests beyond the most simple kind helpful in my code,
but it starts becoming more useful when you have other people modifying the
code.

~~~
MAGZine
this would fall under regression testing, and is most certainly covered by any
list of top reasons to do TDD.

------
mattgreenrocks
Cache:
[http://webcache.googleusercontent.com/search?q=cache:zWk8w06...](http://webcache.googleusercontent.com/search?q=cache:zWk8w063SukJ:omniti.com/seeds/your-
code-may-be-elegant&hl=en&gl=us&strip=1)

Actual article text is a bit more nuanced than the linkbait title. I still
hate reading sentiments like these because they appeal to the lazy parts of
ourselves that don't need any additional encouragement. It's like people revel
in their own laziness and failure to follow-through on some things.

Professionals finish the job, regardless of how they feel.

------
dpacmittal
I must share an anecdote. A recent project was assigned to me which was
outsourced to a consulting company, they ditched the project after 80%
completion. I was required to do the rest. I went through the code and it was
horrible. They had no concept of DRY principle - little code pieces were copy-
pasted everywhere. There was no naming convention, variables were randomly
names, in some places they made use of ORM, other places had raw SQL queries
used with mysql_query() calls. It was a gigantic mess. If the code would've
been organised properly, the rest 20% would've taken me 10 days, now I'm not
sure how long it's going to take. Even though the code works and whatever they
did is functional, but its light years away from maintainable. "Mine works"
isn't always a good solution.

------
mcgwiz
Yes yes, done is better than perfect.

However, it helps tremendously for imperfect code to exist in a disciplined
higher-level organization. In particular for OOP, this means interface and
package/assembly responsibilities should be clearly-defined and leak-free. To
me, this is the minimum ideal--it may never be definitively achieved, but one
should aim for no less. Then, all manner of code abominations can be hidden
and compartmentalized. Various components can be improved and cleaned at will,
without rippling out destructively throughout the codebase.

This means some shortcuts are not allowed, and time to delivery will increase
slightly. But those are the shortcuts that create spaghetti-code and tend by
far to incur the greatest debt. So I see this simple minimum bound as a good
80/20 tradeoff for maintainability.

------
moron4hire
The difficulty of changing code is directly proportional to the amount of code
that has to be changed. This is almost tautological.

So, 6 months ago, perhaps the least difficult thing to do to make a new
spreadsheet report was to copy and paste the first one and change a few bits
of the query. Repeat 10 times. Management is happy, look how many reports we
churned out. Maybe you thought about making a generalized reporting system or
something, but your boss was pressuring you. "It's so simple, just do the
simplest thing. Just make it work."

But now that we have a dozen reports, that asshat in management says he wants
graphs on these reports, even though he told us 6 months ago "no way in hell"
would he ever want graphs on these reports, now he's telling us we're "such
typical programmers, no fucking common sense." Suddenly the change isn't so
easy, we have to touch a metric shit tonne of lines of code.

Technically speaking, it's going to be fewer lines of code to change to copy-
pasta the graphs into all of the existing reports. But we only need to get
burnt once to realize that this management douchebag is going to try to burn
us again in the future. So, we figure it's only a small percentage more
difficult to completely rewrite the reporting system from scratch. And then it
will be easy to add new features in the future.

He is correct in one sense, it should have been done that way in the first
place, but that is the nature of getting burnt, you put your trust into
someone who was untrustworthy. The management asshole put pressure on you to
get the "simple" reports out fast, slow-rolled you on the additional reports,
then doesn't want to hear "excuses" or "details" or anything other than "the
job is done."

So that's where so-called "over engineering" comes from. It's not. It's self
preservation. And at your next job, you'll remember it should have always been
that way, and you dig your heels in on every design decision. And suddenly
you're "that guy" who is always saying "we tried that at our last job and it
didn't work."

I have a policy that I always say I can get the job done. I never tell the
client that they can't have what they want. But I never compromise on quality.
What you want takes a certain amount of effort to create, make sure it's good,
and make sure it doesn't impede our future efforts. Working in this way
ensures I establish a consistent expectation for how the work will go and the
quality of the work over the lifetime of the project. Consequentially, I get
the work done on time and everyone is happy with it, almost always.

~~~
chris_mahan
My experience too. If they balk at the price/time it will take to build a
quality solution, let them go with a lower bidder. They'll come back and
willingly pay this time.

~~~
moron4hire
exaaaactly

------
drcongo
This service is temporarily (and ironically) unavailable.

~~~
acangiano
His server's configuration must be elegant.

~~~
aaren
Or distinctly inelegant and unable to scale to f __*ing working for HN.

~~~
cehlen
Hay! Don’t be a hater. The most important thing is he delivered it on time.
Who cares if you can’t use it? That’s secondary.

~~~
pnathan
I guess he moved pretty fast and broke some stuff.

/cheap shot, it's probably just a wordpress site without caching plugin or
whatever the usual magic is to make it work.

------
ebiester
...unless your sloppy code hides a security bug which, when exploited, costs
them money.

When we work hard to write elegant code, we discover the patterns that allow
us to write better code when crunch time comes.

------
j45
Clever architecture > Clever code, especially when clever architecture
minimizes dependancies and requirements.

Since reading code is infinitely harder than writing code, the next step that
clever coders need to think of is not for themselves, but for others who will
continue to work on what they do if they truly want to be working on other new
and interesting things.

I haven't found my code gets to be automatically "hacky" if it "works" and
isn't obsessed with elegance first. It's usually simpler and approachable by a
greater number of decent programmers that can continue on it.

97% of the time the performance worries we have will never come to fruition,
software rarely gets that kind of pressure, and very few frameworks (I hope)
are that brutal.

Hiding what I do in a clever line of code that slows someone else from
improving it, or taking a small 10-40 ms hit for something far more readable
and editable. If it's a part of the logic that needs further optimization
later, it's ready and willing be improved easily.

One stinking reality is software is just like hardware -- it will always hit
its limits and fail. You can be reasonably kind to your future self, but not
really prematurely optimize everything before it happens, and instead of
making our own lives easier as developers, it should really be about the end
users first.

------
yason
There's basically just one golden rule: a programmer tries to minimize his
total amount of work (because then s/he has more work capability available for
any of the more interesting stuff).

This applies to throwaway code vs. maintainable code as well.

In programmer's head there's a _running judgement ongoing_ while crafting
something new: there are constant decisions on if cheating with quick'n'dirty
hacks is the way of least effort for one part of the software or whether the
total effort will be minimised by expending more effort now to do it in a more
reusable way that saves effort later.

For example, some parts are just written quickly to test another part more
quickly, and that another part might be contained in a module whose interfaces
are really worth designing first and coding later. But some of the code inside
of that could be replaced by a quick hack for now. Good things and bad things
interveawe, interline, and intertwine and in the end just the right places are
done perfectly and just the _other right places_ are cobbled together just
enough to keep the system together.

We occasionally do misses there, but good programmers have a pretty good hunch
on which way to lean at which stage of development and which part of the code.

~~~
jmccree
There's a sub-species of programmer that loves /programming/. Not getting
things done with code, but the act of writing code itself. They'll happily
over engineer and refactor things for eternity if left unchecked. Leave them
alone for two years, come back and ask if Hello World is done? "Not yet, I'm
working on optimizing the text to speech plugin api". It's to these people
that this article should really be speaking to.

~~~
mtdewcmu
Definitely. And there are programmers that love code for its own sake, rather
than for what it does. They seem to be motivated by "what would another
programmer think if s/he saw my code?" \-- rather than, "what will the user
think?"

------
bad_user
MVPs are great, however new business opportunities and new ideas will always
come up on a monthly basis, at least.

Especially in startups, you never have time to take care of technical debt. In
practice, technical debt is dealt with "on the side" and teams that don't do
it will end up in situations in which simple features or pivots are extremely
hard to execute, which will lead to lost business opportunities. I was at some
point in this situation due to a minor pivot that should have been painless
but wasn't, with the solution chosen being to rebuild the product from
scratch. This is why I've been telling my colleagues to always leave the
codebase in a better state every day, even if that means just renaming a
variable. Sloppy code also suffers from the broken-window effect.

What you really want is to write elegant code that works and that's delivered
on time. And the greatest trait of a senior developer is not "cutting corners"
but rather simplifying the problem. That's not the same thing, as the
simplification of a problem often leads to more initial work.

------
gesman
I'd add more controversy here: if deadline is unrealistic it is ok to miss it
and do things the right way.

Deploying ugly piece of shortcut that is going to give you grief for the next
5 years is not worth making for the sake of pulling your skin off to met
unrealistic deadline that was created by the layer of clueless management.

Follow your professional intuition of course.

~~~
JeremyMorgan
So true. Deadlines are the enemy of quality software but if you can push a few
deadlines back up front you can build scalable workable stuff later on and it
pays off.

------
shill
Fast, good and cheap. Pick two. The author's projects require more _fast_ and
_cheap_ than _good_ to be successful. Other projects will have different
requirements.

------
volaski
Your code may f * * * ing work, but my server f * * * ing loads

~~~
frou_dh
Pro tip for those who always do these inane headline reversals: 100 other
people also think of the quip, but they all come to their senses and realise
it isn't worth posting.

------
dasil003
His code may be elegant, yours may f __*ing work, but mine works without the
profanity.

------
nchaud
After 7+ years of intense coding during my work and often evenings/weekends
across many languages, a few months ago I came to the conclusion

"The ability to make those decisions (of where to cut corners), often mid-
project, is what separates veterans from rookies."

I don't have the kahonas to call myself a veteran but certainly, I can now
relate to this. I shall be keeping this article to forward to colleagues at
appropriate times in the future, along with Joel@FogCreek's article on why re-
writing software with the same guys, the same skills and a simplistic - albeit
optimistic - mindset is suicide for your application/service/software.

------
aaronbasssett
They have a CEO, a CAO and a VP of business development but nowhere on their
about us page does it list a CTO or ANY senior level "engineer". And this is
why their company doesn't value doing development right.

~~~
noise
[http://omniti.com/is/theo-schlossnagle](http://omniti.com/is/theo-
schlossnagle)

------
bbwharris
Hey it's not popular here, but I agree with this sentiment. The key is knowing
when and where to make sacrifices. I don't believe in technical debt. I've
seen huge codebases with many lurking dragons. Those dragons solved real
problems, and made the business enough money to employ engineers who are
supposed to be smart enough to work through it.

Real code that "you" didn't write is messy. It takes a long time to understand
the history and context of any sizeable codebase. Perhaps that legacy feature
is there to serve one customer, but it's an important customer who is about to
upgrade to a more comprehensive plan. Perhaps that 100 line function is the
only way to really handle some arcane API without muddying up the rest of the
"better designed" parts.

Code you don't write is the hardest code to maintain, whether it's elegant or
not. Code solves business problems, so without understanding the business or
the specific problem it's trying to solve, you are not educated enough to make
a snap judgement about it's "design" or "technical debt".

I say it all the time, code is not cement. It can be changed. Good engineers
find the constraints, change the parts that are hard to understand and
maintain, and keep everything up and running.

There is no "right way", or magic set of patterns that are going to save you
from the realities of a user facing product.

------
memracom
You danced around one important point about technical debt. True professionals
do not avoid technical debt, but they do account for it. That means that when
we take shortcuts we should be aware of what kind and amount of technical debt
we are incurring, and we should track it, probably in a similar way to
tracking bugs. Then, the stakeholders of the project can look through the
technical debt and prioritise which items that they want to fix and when.

The bad thing about our industry is that too many people take shortcuts and
don't tell anybody about it or keep any records to assist in fixing the
weaknesses that are introduced in the software. Sometimes this is malicious
because a developer is trying to give the appearance of being a mythical 10x
developer.

In fact, I believe that the vast majority of so-called 10x developers are
actually frauds. Most people are unlikely to encounter such a developer
outside of the blogosphere and conferences, unless you are fortunate enough to
work for one of the big technology companies like Facebook, Amazon or Google,
who have the resources to find the real McCoy.

------
mchanson
This article reads like its written by someone trying to extrapolate some
specific experiences of conflict on teams he worked into a general rule.

I would recommend keeping an open mind and looking for programmers to work
with that are able to teach you and that you collaborate well with.

If you find yourself being self-righteous too often when coming home from the
job (or on the job) its time to find new folks to work with.

------
frou_dh
A bit sad that the piece doesn't even acknowledge that not all code is written
for "business" or client purposes.

------
rglover
Another point to add to this: the majority of what we do is ephemeral. I
battled with this idea for a long time (even being 100% adverse to what this
article says at one point), but ultimately I learned to accept the fact that
code on the web is temporary and ultimately subject to change.

A quote by Ethan Marcotte (the guy behind responsive web design) sums it up
nicely for me: "Designing for the web is like building sand sculptures."

Yes, there are certain situations where you should double-down on engineering,
but it's wise to see if what you're building will even be around in a few
months. Not to mention, a lot of the code I write is obsolete by the time it
ships (either by virtue of my skills improving or the framework/language I'm
using upgrading). A guy I have in my Skype list has the most foretelling
status: "you're writing legacy code."

------
JeremyMorgan
While I mostly agree with the article, it's a bit short sighted. "Building
crap is ok as long as it's done".

Whether you plan to stick around long term matters here. Are you just pumping
some crap out at a 6 month contract and don't want to hold up any sprints?
This is a good approach. Are you working at some stepping stone type company
where you don't really care and are looking for something else?

If you're at a company you love and you plan to be there a while, you really
should make a more concerted effort to build better stuff. The shortcuts you
take now will catch up with you later. Also Technical debt is a real thing.

Hacking it and "Getting it done" for some hyperactive project manager who
doesn't understand tech is fine and dandy for the short term, but if you stick
around long enough you'll pay for those sins.

------
pessimizer
Your code may work, but only on your dev environment when the wind is blowing
from the east.

------
maerF0x0
Someone ask Target if they'd rather highend security w/ a missed deadline or
insecure and on time...

The point: Context is king in this matter, it sounds like the OP doesnt work
on things that really matter much (and hence the cost of a bug is miniscule)

------
fleitz
I hear these arguments all the time, fundamentally though as the author
states, using best practices should get your code out the door quicker.

If best practices make your code take longer to develop then one has to
question whether they are best practices at all.

------
ledneb
I think the real sentiment is "sometimes you just have to get things done"
(which I agree with) but I have a few issues. I tried to bake them in to
something which wasn't a bullet-point list, but perhaps this is just how my
brain works...

1) Over-engineering is a separate discussion to elegance, let's not mix them.
2) You can be both on-time and elegant - it's not one or the other, like the
title implies. 3) Often, if that fails, the deadline can be moved without any
real consequence. 4) Consistent failure to be elegant "because deadlines" is
probably going to make later deadlines harder to meet - it seems like a bad
cycle to start.

------
dstefan
I think that is the number one purpose to make software work but doesn't have
to entitle a programmer to do stupid things. The quote from Ralph Johnson
states this:"Before software can be reusable it first has to be usable.". In
my mind, every real programmer likes to write pretty codes because after
reaching higher levels trivial problems are so boring and writing flexible
code kills two birds with one stone. Writing disposable code is another case.
If you aren't interested in programming and don't enjoy it, you shouldn't have
to choose this profession.

------
hugofirth
I actually liked the article much more than I was expecting to given its
opening tone and provocative title.

There is definite truth in the fact that the decision to minimise (as far as
is possible) technical debt accrued throughout a project's journey to release
should be carefully considered if the actual, "real world", goal of the
project is in some way time sensitive.

However I take issue with a number of statements made throughout the article;
Namely:

\- "With that said, "best practices," however you define it, should be a
natural coding standard for any decent developer". In my experience this is
simply not true. A lot of tried and tested best practices (SOLID etc...) are
not necessarily intuitive at all. How would I, as an unexperienced programmer,
have known that the "new" keyword is often a code smell, if someone had not
told me?

\- "If the client needs a Christmas promotion, and you deliver the best
product in the history of promotions -- on December 29th -- it's worthless".
This is true. It is also an exercise in reductio ad absurdum. The author chose
an example with a hard deadline, which is unusual. Furthermore, to turn that
example on its head:

    
    
        No Christmas promotion is due to arrive on Christmas day.
        It might, instead, be due to arrive on December 1st. If
        the outcome of releasing the promotion on time would be
        worse than if it was delayed by a week (i.e. The project
        had major technical flaws), then delaying by a week would
        be the correct decision. This is a decision that business
        men/women should make in conjunction with engineers. Is 
        a working promotion on the 7th of December worth more than
        a non-functional one on the 1st? Probably.
    

Mostly, though, I agree with the idea that engineers should be conscious of
the broader "why" & "when" of their work, rather than just the "what" & "how".
This is often achieved through communication, which should (IMO) be the true
takeaway from articles such as this.

EDIT: Obviously being late on a project is never good. This is why contracts
should have penalty clauses, which should be factored into the decision I
discussed.

------
oinksoft

      > If the client needs a Christmas promotion, and you
      > deliver the best product in the history of promotions --
      > on December 29th -- it's worthless.
    

Isn't the point to set a deadline that allows the product to be built to a
certain standard of quality? If you only ever have time to write untested
copy-paste "code that fucking works" then you don't have a problem with your
development approach ... _unless you 're convinced that's the only way to do
things_.

~~~
treerock
Just reminded me of a story about the designer Peter Saville (from the film 24
Hour Party People)

Tony Wilson: "You've got the posters? It's the fucking gig!"

Peter Saville: "Yeah, I know - it just took ages to get the right yellow."

Tony Wilson: "The gig's over."

Peter Saville: "I know."

Tony Wilson: "It looks fucking great actually - yeah, really nice. It's
beautiful - but useless. And as William Morris once said: "Nothing useless can
be truly beautiful."'

~~~
ctdonath
"Strange how much human progress and achievement comes from contemplation of
the irrelevant." \- Scott Kim

------
rpm33
The higher order bit remains writing high quality code under pressure that
works. High quality encompasses well tested, adherence to abstractions,
maintainable and readable.

~~~
dj-wonk
Right. One key question is this: what does "high quality" mean?

If your product is a first iteration on a web application, user interaction
may be a key part to quality while database tuning may not.

If your product is a data analytics service, database tuning may actually be
very important while the user interaction may be less so.

------
ziffusion
First - it's not about elegance. It's really about organizing, arranging,
structuring the code so that the brain can handle it efficiently (which in
turn gives you the nice properties of maintainability etc.). As a side effect,
the brain also perceives it as elegant.

Second - it is not one or the other. It needs to both work and be
comprehensible. Delivering "non-elegant" code that works though, is job half
done.

------
chris_wot
Your code may be elegant, but mine works. Until it doesn't. And then I spend
hours and hours of time trying to find my bug because of my crappy code.

------
simondedalus
similar to the concept of ockham's razor.

many people with little familiarity or experience with actual philosophical
work seem to believe the razor urges you:

"the simplest explanation is more likely to be correct."

however, the razor actually says:

"do not multiply entities beyond necessity."

the point here--and it's not just for programming or logic--is that you can
make your explanation as big/small complex/simple as you want, but if it's
_more complex than it needs to be to adequately explain what you 're talking
about_, ockham says: cut it down.

if my theory has 1000 elements, your theory has 2, and we predict slightly
different results to some experiment, _ockham has nothing at all to say to
us_. ockham's razor is only useful regarding predictively equivalent theories.
if ockham were saying "keep your predictions simple stupid," his razor would
be trivially bad, and its implications trivially false.

similar to code: if it doesn't work, its elegance is irrelevant. virtues like
parsimony, elegance, or even scalability and the like are built on top of
actually doing the job in the first place.

edit: p.s. people are attacking the article for its strawmen, or for being too
simplistic re: speed vs quality. i don't see how either of those get in the
way of the author's fundamental point: don't overengineer, or mistake
"objective quality" (???) with what's called for in a project. if i'm buying a
$100 laptop, i'm upset that it doesn't have a haswell i7, but i'm not
immediately wondering why the laptop's processor is so bad because it doesn't
have an i7. ideas need to be kept straight.

------
killertypo
Without seeing examples of what they consider "fucking done" and "elegant"
it's kind of a moot argument. Maybe they're already writing decent code, or
maybe their working on short term projects that just need to be finished and
not long standing products that require years of maintenance and ease of
upkeep at the added cost of complexity.

------
vitd
This whole article reminds me of todays article from "The Daily WTF":

<[http://thedailywtf.com/Articles/User-Rejection-
Testing.aspx>](http://thedailywtf.com/Articles/User-Rejection-Testing.aspx>)

"There are only two options here: either you did your job and the application
is correct, or you’re an incompetent and it’s wrong."

------
crazy1van
Elegance is so subjective. Many developers seem to define it as making design
decisions their way. Working is much less subjective.

In my opinion, it's better to focus on improving what is measurable. That
means focusing on making more things work than making things more elegant.

Of course, this whole debate is a broad generalization and the devil is in the
details.

~~~
collyw
I agree, but there are probably some basics that we can all agree on that
makes code inelegant.

I have been rewiting some of my own code recently.It was a quick temporary
solution that grew and grew. I used OOP to avoid cutting and pasting, but I
realise that one central method didn't have any concrete set of input or
output paramaters, it changed depending on what was calling it - very nasty.
It was essentially doing three things, rather than one. (It worked, as the guy
in the article descrbes)

I think seperation of concerns, making one function do one thing etc, is a
start in making elegant code. Or at least not fugly like it was before.

------
notacoward
No it f __*ing doesn 't. Site down.

------
null_ptr
Different projects call for different standards of quality. A Christmas
promotion might as well be spaghetti code if that's what it takes to get it
out the door in time, but if you're doing say an RTOS or a foundation library
then you'd better take the time to do it the right way and respect the craft.

------
MaybiusStrip
Mundane blog post about balancing code quality with business requirements with
a click-bait title. Save your time.

------
pekk
OK, I'll bite. Your code may run today, but it will crash, screw things up and
be hell to maintain tomorrow.

------
sm_sohan
"Your code may be elegant, but mine works" \- of course it works today, who
cares about tomorrow?

------
PeterBarrett
I wouldn't call my code elegant if it didn't do the intended job. Also there
doesn't need to be a compromise between being on time and having elegant code.
With enough experience and planning you should be able to achieve both!

------
jbeja
Well to me is more a matter of pride as a developer, and the quality, readable
and maintainable of my code make so much of it. If i am feeling that i writing
sh __ __*ty code then my pride would be hurt at some degree :(.

------
ForHackernews
This used to be called Worse is Better. It's not a new idea:
[http://dreamsongs.com/RiseOfWorseIsBetter.html](http://dreamsongs.com/RiseOfWorseIsBetter.html)

------
kerkeslager
All elegant code is working code.

Not all working code will be working in 5 years.

------
eklavya
Over Engineering != Best Practices Optimizing only if needed != Cutting
Corners but Bad Code == Bad Code (no justification for it)

------
pistle
Not worthy - not worthy - not worthy. Link bait into troll... This should not
be this high on my HN feed.

------
Akili
"Your code may be elegant, by mine f __ _ing works. "

Really, prove it. Oh wait, writing tests is 'over-engineering' and "Best
Practice", you don't do that. Do you use WinZip every night rather than use an
SCM? yes? your a f_*king idiot.

------
0xdeadbeefbabe
Come on there is a difference between just f __* works and works.

~~~
ctdonath
The development process inspiring profanity as an adjective to "works"
indicates the experience was bad enough to inspire anger, which is not
conducive to a high degree of maintainable quality.

------
piyush_soni
How about a code which works and is elegant as well? Plan better.

------
niix
That site is hideous.

------
crpatino
... (as of today)

------
hubertocarlos
trolling. got to be.

------
ninjac0der
... and as expected, it's always the manager, not coding types that state this
so aggressively. I know the servers are beefy at OmniTI, so I suspect there
might be a code problem related to handling the load.

If I see sloppy code, or have to write sloppy code, I move to another company,
and will continue to do so. So how's that employee turnover rate (hint, use
the internet archive and check the about us page)?

~~~
varjag
I am a coder type, and I mostly support the sentiment.

Over the years, I gradually drifted from doing things the Right Way to doing
things that are good enough. Doing things elegantly in practice unfortunately
adds zero flexibility for non-trivial changes in business direction: you
simply can't foresee everything. One swift decision at mid-management level
and your elegant framework suddenly becomes an unwieldy Titanic impossible to
put into a quick turn.

Now arguably works-for-today kind of solutions are not inherently any more
flexible. However, they don't take nearly as much investment in the first
place.

(Should also point out that quick and simple is not equal "sloppy code": I
check my return values and handle errors just fine, it's just that my code
makes no attempt at establishing world peace).

~~~
dsrguru
> Doing things elegantly in practice unfortunately adds zero flexibility for
> non-trivial changes in business direction: you simply can't foresee
> everything. One swift decision at mid-management level and your elegant
> framework suddenly becomes an unwieldy Titanic impossible to put into a
> quick turn.

Yes and no. If you're writing very elegant statically typed functional code
like in Haskell or ML, you're going to have to be elegant at the design level,
and yes, you might have trouble adapting to new requirements. But if you're in
a domain where requirements aren't always set in stone, you're probably using
a more dynamic environment where you don't have to be what the OP called
"elegant" at the design level (e.g. his unrealistic caching layer example),
but you can still write elegant code at the micro level (within functions,
classes, etc.), which will almost certainly lead to substantially less
technical debt and shouldn't cost much if any more time than quick hacks at
the micro level.

