Hacker News new | past | comments | ask | show | jobs | submit login
Your code may be elegant, but mine works (omniti.com)
164 points by mendicantB on Feb 5, 2014 | hide | past | favorite | 168 comments



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.


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.


I was involved in a software development project last year, in which the entire remote development team of 20 people got fired, because the software architect implemented a bunch of best practices, design patterns and state-of-the-art frameworks, without any thought as to how this would impact development time. The problem was that he was the only one who was familiar with most of this stuff, so there was a very steep learning curve for the rest of the team, who one by one either dropped out or became totally unproductive. After 18 months in which he burnt his way through the budget, with very little to show the client by way of results, the project was drastically scaled back. So this is not just about straw men. People like this really do exist.


Things like best practices become more important the larger the team. Are you suggesting the project would have been more successful if they had been less concerned about code organization and unit testing (or whatever you mean by "best practices")?


The problem was not the use of best practices per se, but the uncritical use of these practices. For example, it's good to use design patterns, but not every pattern is appropriate to every situation. We got to a point where it might take a full day to make a change to a table, and then make the corresponding changes to all the various repositories and entities. Similarly, it's good to use the latest technologies, but using beta versions of unpublished frameworks was a bit over the top, both because documentation was scarce and because they were still buggy.


"Nobody is calling spending weeks writing a caching layer for a 20-row database "elegant" or "best practice"

I don't disagree with your main points, but you might be surprised to hear some things that people will say and unnecessary optimizations they'll attempt...


> Nobody is calling spending weeks writing a caching layer for a 20-row database "elegant" or "best practice". That's a complete straw man.

Have you used any Java API? That's exactly the feeling I get from using them.


I use plenty of Java APIs. It's a vast ecosystem of code, generalising across all Java libraries ever is silly.


The people who make the most noise about elegance and best practices generally dislike Java for precisely that reason.


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.


A lot of the time once you have a good understanding of some of some more mature practices it doesn't take any longer to do the 'right' thing.


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.


I felt the same about the YC ecosystem, which is why I submitted this.


Exactly. Specially with the chosen title.

Almost all similar articles I read, are used as some kind of self justification to writing bad code and leaving it there forever.

If you believe the software will fail (won't ever be changed/grow), do whatever you want with it. If you think it'll succeed, stack too many dirty hacks together and you're gonna pay for it later with tons of interest.

Main problem is, too many times this goes "unnoticed", people just take longer and longer to do the same things, but people stay oblivious to the real causes of that technical debt.


> Almost all similar articles I read, are used as some kind of self justification

Nerds (of which I am one) tend to be really good at rationalization. These articles serve as a sort of catharsis ("I probably could have done better, but I was really just moving fast and breaking things!"). Other times, these articles are written as a means of projecting identity (e.g. "I reject enterprise-y nonsense by refusing to doing any sort of analysis or design!")

Both are exceedingly poor motives.


Nerds ( also one myself ) tend to suffer from the over-generalization fallacy. Whereby they think that their local experience generalizes to a much larger scope. For instance, If you read most of HN programming articles with the prefix "when writing code for a web startup" they make sense, if drop that prefix they stop making sense. It also helps to keep in mind that advice that holds in the startup world can be quite toxic when applied elsewhere in the industry.


Definitely. I disregard most 'engineering' advice I read in HN threads for exactly this reason. Most of it falls into the "I don't believe it's an issue in my 1.5k LOC app, so it must not be real!"


A while back I tried to add some clarity to the discussion.

http://deliberate-software.com/quality-is-future-speed/


Meta comment: The article: (a) covers enough relevant topics (b) using rather ambiguous terminology (c) while offering sharp opinions (d) about a world of pain (e) that we all experience (f) but can never be solved in general

This is not a bad formula for crafting a blog post that you want to get picked up via HN. It is also a great way to start a discussion that will never end.


>Reducing software development practices down to these cute catchphrases is a bit disingenuous.

Its a bit like Scientology, but without the crazy.

Oh no, wait .. there's plenty of crazy.


Same idea, you reduce arguments down to these repeated definitive-sounding cliches that are held sacrosanct and impenetrable to dissent.


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.


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.


I wouldn't go quite as far with the generalization, but this notion is very important.

Just as developers are often skeptical of a business leader's motivation (is it right for customers or just for his/her ego? etc.), business leaders can be skeptical of technical debt and code quality arguments not because of the concepts themselves but the motivations behind the person doing the arguing.


ditto. Phony concern for technical debt is the perfect cover that many developers use to further their own ideology instead of simply focusing on getting things done.


Technical debt can be a very real issue though. I always strive to highlight the 'interest' we are paying on our technical debt to our product owners, so that they understand what deferring necessary work is costing them.


If it is elegant then it won't have tight coupling everywhere. Presumably by "elegant" you really mean inelegant.


Hence the quotes. What I find interesting is that there's a class of developers for whom their quest for elegance results in the exact opposite of elegance. You can spot these developers by a complex class hierarchy that does absolutely nothing, a complex configuration management system that allows you configure everything at runtime except the settings you want to change, which requires recompile and over-engineered replication of the underlying platform or a library and an occasional commit or two that rewrites perfectly good working code to adhere to their idea of what's good, while introducing bugs and incompatibility.

This kind of behavior seems malicious but I think it's more often the result of wishful thinking. A lot of these come as a result of imitating good design without understanding the context that makes those choices good or even necessary.


> You can spot these developers by a complex class hierarchy that does absolutely nothing

Oh yes, most definitely. Why have one class when you can have three classes that provide the same functionality?


Sounds more like Cargo Cult programming than an attempt at elegance.


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.


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.


> 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.


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.


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


haha, I am sure there are many buggy spreadsheets out there...

I didn't mean to suggest that it doesn't require knowledge and effort to put together a sophisticated spreadsheet but relative to building even the simplest web application, spreadsheets are a breeze.


This is a problem, and I've long mused over possible solutions. Every time I think about it, I come to the conclusion that the solution isn't a new approach to software engineering, a new language that blows away every paradigm, some abstraction that promises to make app development simple, or any other silver bullet.

Indeed, the only "solution" I see is a solution in just the loosest sense. Namely: We continue incrementally improving languages, frameworks, libraries, and coding practices--a process that has been going on since software began. That's a disappointing answer, but I think it's the only answer, and I'll explain why.

The complexity of the tools we use is a result of their great flexibility and power. For example, a Ruby on Rails app is a huge agglomeration of technology, including HTML, JavaScript, jQuery, CSS, SCSS, Ruby, the Rails framework, and usually a number of other, project-specific technologies. All of these technologies must be learned (no small task), and their quirky interactions with each other must be managed. One sometimes thinks, "There must be a better way! There must be some abstraction that can hide all this technology." But I challenge anyone to design such a thing.

Each of those technologies is mature. Each one has had tremendous effort put into designing the simplest possible API without sacrificing power and flexibility. Even technologies with a lot of baggage, like HTML, CSS, and JavaScript, have seen substantial improvements in recent years. Given that, does anyone think they can do better? Can anyone do everything these technologies do and present a radically simplified API? Remember, you can't sacrifice power and flexibility and just support the most common use cases. Almost any application will need at least one thing that's unique or idiosyncratic.

This is why people use Rails (or similar tools) for custom apps instead of Wordpress. Wordpress has many off-the-shelf plugins that provide commonly-needed features. From a site maintainer's perspective, Wordpress abstracts away most of the complex web programming inherent in those features. But for serious app developers, that's almost never good enough. The plugins never seem to work exactly as you need them to, and they rarely talk to each other the way you would like. A short ways into the project, you're forced to either hack up your plugins, which is a maintenance disaster, or code your own plugins, which means you're really just using Wordpress as an inferior Rails substitute.


A good tool does not need to throwaway existing frameworks or paradigms in order to deliver. I am a firm believer in using what's already proven.

>The complexity of the tools we use is a result of their great flexibility and power.

This may see like a strength but it is actually a massive weakness. Existing IDEs attempt to be all things to all people and as a result are not actually delivering the best that they could if they were more focused.

>Given that, does anyone think they can do better?

Download our software (check my profile for link) and spend some time playing with it, you might just reconsider that position :)

Or join the newsletter, we are coming out with an exciting update that is basically going to attempt to combine wordpress-like application composition within an IDE.


I looked at Crudzilla. (Is that the product you're referring to?) I don't really have the time to test-run a new framework right now. Perhaps you could give a quick overview of how you're solving the key problem I identified above? To recap, my argument is: The web stack must be flexible and powerful, because nobody's abstraction layer can anticipate the weird, idiosyncratic little needs of most real-world projects. Thus, the flexibility and power of the dominant tools, like Rails and Django, can't be sacrificed in the name of simplicity. Or if you do make that sacrifice, your tool will only be useful to the tiny subset of applications that fit into your narrow definition of how an app works or what it does.


I see intrinsic informational limitations. Software developers and managers learn, but they also forget. Also, technologies change, so knowledge "rusts" over time. So the rational ability to make information-based trade-offs is dynamic. Now, think about competition and you can see why this gets complex. I wouldn't be surprised if there is a system dynamics paper on this phenomena.


And this is why I won't work in any industry where "a time-sensitive situation [where] your code will only be used for a brief period of time" is business-as-usual. Like, for example, the games industry.


I like seeing this probabilistically!

That said, I think the operative decision is "should I cut the corner?". If so, you should also factor in the p( ___ | not cut corner ) probabilities.

So, you should cut the corner if the benefits exceed the costs. Written out:

    p(~P|C) * b(~P) - p(P|C) * c(P)
    >
    p(~P|~C) * b(~P) - p(P|~C) * c(P)
Symbols: p = probability; b = benefits ($); c = costs ($); P = problems; ~P = no problems; C = cutting corner; ~C = not cutting corner.

Rearranging to:

    p(~P|C) * b(~P) - p(~P|~C) * b(~P)
    >
    p(P|C) * c(P) - p(P|~C) * c(P)
Then you get a simpler form:

    b(~P) * (p(~P|C) - p(~P|~C))
    >
    c(P) * (p(P|C) - p(P|~C))
An amazing fortune awaits any person who can simply evaluate this inequality in real-world situations.

It is also useful to know when the cost of gathering the information to evaluate the expression is not worth the potential benefit!


Definitely, thanks for adding in those terms. I kept it simpl(er) and left out the extra terms because I think that those two terms (benefit from cutting the corner vs loss of not cutting the corner) are the major factors when making the decision as they can have big effects on the business itself, while the other terms are just shifting around a bit of extra money/time. Maybe. It would depend on the corner.

Everyone just thumb sucks it in the end anyway - I'll just embed this domain name in the distributed binary, nobody will ever steal our domain name! Technically someone at this point should pull up the statistics for stolen domain names to get an estimate for the probability, and work out how much it would cost to set up a system to pull a correct domain name from a backup, and then work out the cost to redistribute all the binaries to end users whose software won't be working for some time. I doubt anybody has ever done that particular calculation.


This estimate gets easier with a couple decades of experience. Which is why I'm always surprised by the agism vibe that sometimes resonates on HN.


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.)


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).


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.


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.


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.


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.


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.


> 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.


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 :(


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.


Yeah, the code may work, but making changes to it may make me want to shoot myself.

I work with the same types of devs, and modifying/extending their code could lead one to alcoholism. Seriously. No joke.

I have quite honestly considered changing teams, just to get away from a code base that may "work", but induces nightmares.


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.


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/


Yeah, my team has inherited similar code from one particular Boy Wonder. One example was a service that imported JSON from third parties - it was unit tested, but the architecture was so poorly testable that it had mocked dependencies three levels deep. We also picked up a home-rolled reporting tool that was an instant injection of significant technical debt.


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?


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


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...

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.


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.


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.


> 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.


Perhaps the concept of Technical Bankruptcy should be introduced.


"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.


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...


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.


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!")


> 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.


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.


Great quote.

I think we all understand that spaghetti code simply adds time to the next feature we want to introduce, probably creates unseen bugs, and might explode. But it's always a balance and nothing is black and white.

I hear a lot of "you're wrong, do it the right way first!" but you gotta balance "the right way" with its context. Code isn't made for code's sake, it's made to do something (like a business objective, like "be able to order a book through my browser"). Businesses are trying, first and foremost, to make profit, however they need to do that. Beautiful code has nothing to do with that goal, but is sometimes a means to that end.

If the code achieves the business objective it was meant to achieve, it's doing its job (however minimally). Customers don't care what the code looks like (if they look at it). They just care that it does what they need to do (like order a book). Businesses don't care what the code looks like as long as it makes profit.

Secondary to the business objective is how that code fits into the greater context of the system-as-a-whole. Obviously badly written code is going to accrue technical debt, which will likely lead to cumulative delays to new features, cause things to break, etc. The extra effort involved in dealing with that debt is obviously going to cost something, which will have an affect on the primary goal of business: profit. But also delaying a feature, to "do it right the first time", that could be earning revenue, is also going to affect profit. The key is to balance it to maximize profit overall.

When I do anything (code, draw, write, cook, paint, dance, whatever) I start by doing it the simple, easy, fast way; I probably fuck it up; then I iterate and try to improve upon it and refactor. Usually in getting something out there I discover new solutions that I would not have seen had I not actually made something and put it into the world where I could look at it and point to it and talk about it with other people. Being an early mover aside, I think this kind of process helps overall quality anyway. And in the meantime I've got something that's at least doing something.

I think Joe Armstrong knows what he's talking about ;)


This sentiment is why I only work in domains that value high-quality work. My definition of high-quality is something that's done well enough that it doesn't have any obvious issues, based upon the current product vision. It should be designed well enough that we can move onto subsequent requirements afterwards.

My clients/employers don't have a say in the quality of the finished product they receive. (They may be angry about this, but my responsibility is to my profession first, and them second.)


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".


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.


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

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


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...


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.



No, actually it's not. This isn't ignoring the issue at hand and just attacking the author's character, it's attacking the authors authority on a subject matter.


If one focuses on personal characteristics (here skills) of the author rather than the logical construction of his argument, it is in fact ad hominem.


No it's not. If the author's methodologies result in undecipherable code, that's quite relevant to the discussion.


The author has presented an argument. Whether the author himself generates any code at all has absolutely no effect on the validity of his arguments.


Since when is credibility not a thing?


His arguments can be validated only based on its internal logical structure. One should not try to invalidate it based on his claimed credibility. That's ad hominem.

See here: http://plover.net/~bonds/adhominem.html

Example:

A: "All rodents are mammals, but a weasel isn't a rodent, so it can't be a mammal." B: "I'm sorry, but I'd prefer to trust the opinion of a trained zoologist on this one." B's argument is ad hominem: he is attempting to counter A not by addressing his argument, but by casting doubt on A's credentials. Note that B is polite and not at all insulting.


Credibility is a heuristic to determine what arguments should be evaluated and which should be discarded. It is not reasonable to expect every person to critically evaluate the word of every person who has something to say on a subject.


...Not sure you know what "Ad Hominem" means...

This is not a disaccreditation of the man based upon his character or something unrelated to the topic, his ability to write good code is highly relevant to the issue at hand.


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.


>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.


O-TI makes money fixing broken shit.


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.).


> "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.


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


Cache: http://webcache.googleusercontent.com/search?q=cache:zWk8w06...

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.


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.


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.


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.


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.


exaaaactly


This service is temporarily (and ironically) unavailable.


His server's configuration must be elegant.


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


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.


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.


Whoops, running the frontend cache in debugging mode:

https://twitter.com/postwait/status/431117981922631681


...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.


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.


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.


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.


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?"


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.


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.


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.


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.


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


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.


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


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.


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.



wat


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.


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.


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.


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


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."


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.


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


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)


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.


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.


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.


  > 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.


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."'


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


Oscar Wilde: "All art is quite useless"

Therefore, no art is truly beautiful?


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


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.


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.


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.


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.


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.


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

<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."


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.


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.


No it f*ing doesn't. Site down.


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.


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


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


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


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!


This used to be called Worse is Better. It's not a new idea: http://dreamsongs.com/RiseOfWorseIsBetter.html


All elegant code is working code.

Not all working code will be working in 5 years.


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


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


"Your code may be elegant, by mine fing 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.


Come on there is a difference between just f* works and works.


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.


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


That site is hideous.


trolling. got to be.


... 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)?


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).


> 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.


So the key is making the right call for the situation, which brings me back to the point, managers are not the ones maintaining the code.


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.


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 :(.


... (as of today)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: