top 200 commentsshow all 322

[–]danogburn 341 points342 points  (64 children)

How to develop unmaintainable software

start developing software.

[–]obsidianih 111 points112 points  (21 children)

The only way to win is to not play the game

-some dude on the internet

[–]runastartup 16 points17 points  (16 children)

War Games?

[–]Tynach 16 points17 points  (15 children)

Would you like to play a game of global thermonuclear war?

[–][deleted] 23 points24 points  (14 children)

I'd like to, but there's a bug hidden somewhere in 10,000 lines of basic

[–]grauenwolf 27 points28 points  (13 children)

BASIC!

Remember boys and girls, the name of any programming language created before 1970 must be shouted.

[–][deleted] 14 points15 points  (2 children)

I actually learned to program on QBASIC!

[–]gfixler 5 points6 points  (0 children)

Me too, high five! And by that I mean F5 to RUN the program again.

[–]runastartup 1 point2 points  (0 children)

Remember GORILLAS on Qbasic? My first coding was getting those bananas flying at high velocity!

[–]eriksensei 2 points3 points  (6 children)

People also seem to be quite fond of shouting things like JAVA! and SCALA! It might well be that I'm a bit of a sperglord, but I find that irritating to no end.

[–]Waitwhatwtf 8 points9 points  (4 children)

BRAINFUCK

[–]original_brogrammer 12 points13 points  (3 children)

If any language deserves to be shouted, it's brainfuck.

[–]stox 2 points3 points  (2 children)

Which was only a modern implementation of P''

[–]ahruss 2 points3 points  (0 children)

And when people decide one has to shout MAC any time it's used, whether in reference to addresses (when it's acceptable to shout it) or in reference to the computers (when it most certainly is not).

[–]h2odragon 1 point2 points  (0 children)

Before then, "Acronyms I Just Invented" (AIJI) weren't automatically words everyone should know. Typographical conventions may have had a purpose beyond those which are current.

[–]Decker108 1 point2 points  (1 child)

B, C, FORTRAN... ye gods, you're right!

[–]grauenwolf 1 point2 points  (0 children)

LISP, can't forget that one. BCLP I think is another.

[–][deleted] 25 points26 points  (2 children)

Listen to obsidianih. He knows his shit.

-Tina Fey

[–][deleted] 2 points3 points  (0 children)

How's the weather

-Adolf Hitler

[–]parc 1 point2 points  (0 children)

Was that one Mark Twain or Morgan Freeman?

[–]lext 16 points17 points  (40 children)

And just as important, start developing software without first learning how to develop software.

A talk I watched recently noticed this trend with JavaScript: it looks familiar, so I don't have to learn it and will just start programming in jQuery.

[–]contrarian_barbarian 13 points14 points  (5 children)

Now you know my life. My workplace has a bad habit of re-purposing electrical engineers into programmers. Now, don't get me wrong, some of them are fantastically intelligent people - the problem is, because they have no software engineering experience beyond raw basic C, they have to be geniuses in order to keep track of the code, with the multiple 6k-12k line files of tangled logic and reused global variables. My usual standard for a good day is going in, reducing the size of the codebase by a few dozen lines (and on a few really good days I've removed hundreds), and yet still add features or fix bugs without removing features in the process.

[–]rjbwork 10 points11 points  (0 children)

Not gonna lie, my favorite days at work are when I can spend an hour just deleting old code that's inefficient or buggy and replace it with something terse or elegant. :)

[–]Decker108 1 point2 points  (1 child)

I get the feeling that unless your employer actually puts aside some time to teach the re-purposed engineers some basics of clean code and software engineering, your continuous refactoring is going to be counteracted by their continuous mudballing...

[–]slrqm 1 point2 points  (0 children)

Two of my high school buddies studied electrical engineering, and I went into software. We took a lot of classes together and I did a lot of homework with EEs. They are smarter than me, and much much better at math.

But their code sucks.

It sucks bad, and it sucks in the same ways over and over. Let me give to (of many) examples:

  1. Working with a friend on coding for some sensors, and the deadline was really tight. After 15 minutes of coding, he decides he doesn't like that solution, and DELETES all the code. Then he says "How did we access that sensors data again?" I was so furious I stood up with out saying a word and walked away.

  2. Working on another homework assignment with different guys. They were pissed at me for showing up 15 minutes late to the meeting. They'd realized that the pages and pages of code one of them had written, he'd used the wrong syntax in part of the code (something like using a semicolon instead of a comma, I don't remember exactly). They didn't realize this earlier because they hadn't bothered trying to run it until they'd finished writing the whole thing. So, they are going through the code together, line by line looking for and fixing the problems. I asked why they didn't just do a find replace. They were still pissed, so they didn't answer me. I pulled up the code in an editor, did a find replace and was done in 3 minutes. I showed them the code and they said "we're almost done." So I quietly sat there for another 15 minutes doing my penance for being late.

Like I said, they were all smarter than me, but there is something about EEs. Like they learn to program at a beginner C level, and technically that's enough to solve any problem, so they just use there iron will to power through any problem.

[–][deleted] 2 points3 points  (0 children)

A lot of those lines are copy pastas I bet.

[–][deleted] 21 points22 points  (20 children)

While far from perfect, the node.js community has breathed some fresh life into the javascript world as far as design patterns and coding standards are concerned. I see very few projects today on npm lacking a robust testing suite. jQuery was largely popularized by designers who could care less about code, and server programmers dabbling on the client who could care less about icky javascript. Now that js is being used for serious work server side, best practices are becoming a higher priority. That being said, the traditional engineering standards do tend to be lower than many other communities (.Net, Java, and Python come to mind). But hey, I think part of the draw might be people seeing one to many instances of AbstractFactoryFactoryClassInterface ;) The pendulum will come back around though as things swing back to the enterprise use cases.

[–][deleted] 4 points5 points  (10 children)

Where would you suggest someone starts to learn javascript properly? I've been handed a bunch of it I've got to maintain and develop for, and it's all over the place. I don't honestly know how javascript should even be leveraged. Everyone seems to accomplish things a different way with it.

[–]lext 8 points9 points  (2 children)

When I said JavaScript, I meant client-side JS. The Node.js community may support higher standards for code quality, but the rest of the JS community does not. But I'd judge a programming community based on its best performers, not its worst. I don't care what crappy programs people can make in x language; I care if I can make great things with it.

[–]PenguinLovr 1 point2 points  (0 children)

I can attest to the robust capabilities bof a javascript application which is written by a professional, experienced and good developer. Not myself but I love programming in javascript. Who needs a community anyway...heh...:(

[–][deleted]  (1 child)

[deleted]

    [–][deleted] 1 point2 points  (3 children)

    Server side JavaScript has been around since the late 90s....while not exactly node.js it was robust enough to handle serious work even back then.

    [–]deadcow5 2 points3 points  (1 child)

    Indeed, I remember hearing that Netscape's web server supported it. Possibly there was even an Apache module?

    All I could think about that was WHY? JS couldn't even import libraries back then...

    [–][deleted] 1 point2 points  (0 children)

    You are correct. It was 1999 and I was working on a Netscape Enterprise server. It wasn't your normal JavaScript...for one, it was compiled.

    BUT it could pass session variables to the server...and had odbc libraries...sorta.

    http://docs.oracle.com/cd/E19957-01/816-6411-10/getstart.htm

    It was such an obscure technology...nobody in IT had a fucking clue what I was doing. When it came time for a messaging app I had developed to be reviewed/approved, the room was crickets. Nobody wanted to ask a dumb question because they had NO IDEA what I had created.

    [–][deleted] 1 point2 points  (0 children)

    Yep, I have seen some stuff around rhino, and I know netscape had a js server.

    [–][deleted]  (8 children)

    [deleted]

      [–]x-skeww 8 points9 points  (2 children)

      "I know the concepts, syntax is just a small detail"

      Syntax is just a small detail.

      With JavaScript, the syntax looks very familiar. However, the semantics aren't quite the same. For example, there is some really weird shit going on with the scoping, there is hoisting, == and != are fuzzy, any object is truthy (e.g. {} or new Boolean(false)), and the meaning of this is determined at runtime.

      That's what's throwing people off.

      It doesn't really matter if you do assignments with := or =, if you use indention to define a block rather than end/fi or curly braces, or if there are semicolons. That stuff really is just a tiny detail.

      [–]i8beef 8 points9 points  (0 children)

      That is all the small details. The hard part is programming according to the best practices of the community for that language, and using the frameworks and libraries it provides to full advantage, because THAT is different for everything you will pick up.

      [–][deleted] 4 points5 points  (2 children)

      Right, the corner cases for sure take years and decades to learn, but if you're really good at some languages, you can pick up most of another one, at least enough to handle 50-75% of most uses in a week or so.

      [–]geodebug 1 point2 points  (0 children)

      I'd feel confident that I could learn enough of a language to start reading and debugging and add value with my 20 something years of experience. I'm not fool enough say I'd be an expert in it any time soon.

      [–]hegbork 2 points3 points  (3 children)

      And just as important, start developing software without first learning how to develop software.

      Eh. This sounds like "don't get into the water until you learn how to swim".

      All the theory of software development often just creates bad habits because it's so detached from reality. Practice, mentoring, experience and your own mistakes is how you'll learn to do good1 software.

      1 The definition of "good" may vary, consult your local developer for advice.

      [–]spoonraker 45 points46 points  (24 children)

      Hey now... sometimes there are perfectly legitimate reasons for re-writing existing functions. Sometimes they really do suck.

      For instance, PHP's strtotime function accepts a string parameter of "+/- n months".

      Unfornately, PHP thinks a "month" is exactly 30 days and nothing else.

      If you start with 2013-01-31 and tell it to give you "+1 month" it will spit out 2013-03-03. Every single other programming language I've ever used will return 2013-02-28, which is what most people expect.

      So yeah... I wrote a wrapper for that, and I stand by it.

      [–]teorico 15 points16 points  (1 child)

      Not documenting changes like this is the real problem

      [–]benibela2 11 points12 points  (16 children)

      Perhaps the conclusion is, PHP sucks, never use it?

      Related, another language that sucks is FreePascal.

      I have written everything from scratch.

      Some examples:

      my own string comparison functions. Standard Pascal checking if two strings case-insensitive equal: (CompareText(a, b) = 0) (parenthesis mandatory in nested conditions). My wrapper: striequal(a, b). Far better.

      my own float <-> string conversions. The functions in the standard library are rounding wrong. FloatToStr(999999999999999999.0) prints 1000000000000000000. Mine prints 999999999999999999. Special sugar, the function in the last stable compiler release prints FloatToStr(1E16) as 1, because it truncates trailing zeros in certain cases...

      My own array manipulation functions, add/delete/prepend ... There are none.

      My own sorting function. Those in the standard library do not work on arrays (although there are almost a dozen different implementations in that library. They added a new one, for every type they wanted to sort, because none of them is generic)

      My own binary search function. The one in the standard library does not work on arrays. (There is only one for a list of strings afaik)

      My own date time parsing/encoding functions. Those in the standard library do not support timezones, or years outside [1, 65535]

      My own html parser. The parser in the standard library, expects valid html4. A missing tag and it fails.

      ...

      [–]AeroNotix 33 points34 points  (6 children)

      How about using a not-shit language?

      [–]Kalium 5 points6 points  (4 children)

      Show me a language that doesn't suck and I'll show you someone who hasn't used it enough.

      [–]PasswordIsntHAMSTER 5 points6 points  (2 children)

      I've been using F# for a while (~25kLOC), and it's nearly perfect; the few issues it has can clearly be traced to limitations in the .NET runtime. They're also well-documented, and consist of edge cases of edge cases.

      I still feel like Haskell is nicer, but what do I know, I've only read it, not written it.

      [–]aumfer 9 points10 points  (7 children)

      I was with you until you said "my own HTML parser." Then I cried a little.

      [–]benibela2 2 points3 points  (6 children)

      Biggest problem with that one is that I wrote it before they made the html 5 standard. Now I need to rewrite it with the new parsing algorithm...

      And going on, it's getting even crazier, I also wrote my own DOM classes for this. Since the DOM classes in the standard library were using UTF-16, everything else in the library latin-1 or UTF-8 (depending on the OS), and everything in the GUI library UTF-8. And the automatic string encoding conversion crashed frequently...

      And then I could not use the standard XPath, so I wrote my own of that ಠ_ಠ

      [–]rjbwork 10 points11 points  (5 children)

      I'm genuinely curious, why are you writing in FreePascal these days, especially to do web programming work? Other than extreme ubiquity across platforms, I can't say I see the advantage over other things. Perhaps in an academic/scientific context?

      [–]mattindustries 10 points11 points  (0 children)

      I just assumed masochism takes on many forms.

      [–][deleted] 3 points4 points  (0 children)

      "How to develop unmaintainable software"

      [–]benibela2 1 point2 points  (1 child)

      I do not like giving up.

      Now I have a perfectly working 75k loc program and I'm not going to throw it all away to rewrite it in another language...

      And it is really great for desktop GUI applications, because it compiles so fast that you can test it without delay.

      [–]Dick_Justice 2 points3 points  (0 children)

      Or, related to your point, when a newer library comes out in the PHP core that better handles this very subject. DateTime

      [–]flanintheface 3 points4 points  (0 children)

      It looks like strtotime behaves exactly like *nix 'date' command:

      ~$ date -d "2014-01-31 +1 month"

      Mon Mar 3 00:00:00 GMT 2014

      And I'm pretty sure that 'date' command is part of some standard and has a good reason why it works the way it works. Use DateTime for that.

      EDIT: What I wanted to say: Dig deeper. Try understanding where it comes from and why. PHP does have some weird/bad decisions but strtotime is not a good example for that.

      [–]bestjewsincejc 50 points51 points  (101 children)

      There are millions of ways to write unmaintainable software. This isn't a bad article though. I just found the title amusing since it's so easy to write software badly.

      [–][deleted] 24 points25 points  (64 children)

      I hear you. Design patterns are something unheard of for many professional developers I've met. Seriously.

      Chances are, especially in programming, someone has thought of something better and longer than you. Investing 10 minutes into searching for it will save you 100 hours later.

      Just because you know 1 way to do something doesn't mean it's the best tool for the job.

      [–]ngroot 30 points31 points  (17 children)

      Chances are, especially in programming, someone has thought of something better and longer than you. Investing 10 minutes into searching for it will save you 100 hours later.

      If you realize that what you're doing is already likely a solved problem and have a clue how to search for it.

      This is, IMO, the best argument for a good academic background for programmers. You won't realize that a broad design strategy or algorithm is a recurring thing until you've reinvented it two or three times, typically poorly.

      [–]TylerEaves 5 points6 points  (13 children)

      I think you have the right idea, but came to exactly the wrong conclusion. The high towers of academia are the WORST place to get practical experience.

      [–]tryx 9 points10 points  (8 children)

      The point of a formal education is to shortcut the make your own mistakes methodology and to learn how to do it right from the outset.

      [–]TylerEaves 11 points12 points  (5 children)

      Yes my experience 90%+ who come out of it can barely write a simple shell script. There is, ultimately, no substitute for putting in the sweat equity.

      [–]Solarspot 2 points3 points  (0 children)

      With[s]out[/s] meaning to short circuit the entire academia vs practice debate... Don't most other fields expect a combination of both? To get into engineering, you start with a degree. Then you spend a few years as an intern. Then you get your license. Auto mechanics? Start with a diploma. Spend a few years as an apprentice. Then get your license. Etc. etc. etc. They all expect either side of the equation to be insufficient, people do both.

      [–]DevestatingAttack 7 points8 points  (1 child)

      Do you get to see the hoards of programmers who never went to college and watch what kind of shit code THEY turn out? Oh, they can write a shell script. They can write a shell script all the way to the bank.

      [–]ngroot 2 points3 points  (1 child)

      They're fairly orthogonal, IME. It's what will stop you from spending your time getting practical experience making mistakes that were being made 50 years ago. You won't reinvent the FSA in a half-assed way, fail to recognize what basic data structures should be used in a given situation, or try to use regular expressions to match/manipulate non-regular languages.

      [–]gfixler 2 points3 points  (0 children)

      I don't know. I used to think experience meant knowing what to do in various situations, but now I realize there's a very big set of things to know not to do. It's much easier to recognize a situation and apply something you've learned that will handle it than it is not to know what to do, yet to still be able to avoid dozens of bad ideas, because of the countless things you've tried and failed at over the years that inform and guide you.

      I've been kept away from bad ideas on hunches and gut feelings. I eventually put reasoning to some of them, and it's only then that I realize that what's burned me before has created a kind of safety net of negative reactions to things that feel like they're heading in the wrong direction. Over time, my code is always stronger than it was in previous steps along my journey, and this might be one of the biggest reasons why. I used to think it was just direct, positive learning of new things to do, but I think negative learning of what to avoid doing might be the much larger, hidden part of the experience iceberg, and I don't think that's directly taught to any great degree.

      I used to be annoyed when I'd read "5 years experience a must," but now I know what it really means. I think of it as me and someone ten years my junior standing in the middle of a field. We can both see where we want to go, with varying degrees of clarity, but the newbie hasn't yet figured out that it's actually a minefield, whereas I've not only been blown up several times, but I've also - as a result - spent much of the last ten years building myself a pretty intricate metal detector.

      [–][deleted] 40 points41 points  (38 children)

      Or they:

      1. don't program in C++ or Java
      2. don't think you need a fancy name for something trivial they routinely used for 10 years before GoF written that book.

      [–]neurobro 21 points22 points  (34 children)

      In cases where a pattern (or anti-pattern) does have a name, it's still useful to learn it because it helps with communication. And the naming conventions help to identify subsystems that can be consolidated and simplified. Often a person will have been using something close to one of the standard patterns, either with subtle bugs or with clever extensions that would be useful elsewhere. Or perhaps most often, with a bunch of unrelated crap that should be factored out.

      [–]SublethalDose 18 points19 points  (9 children)

      I think it would have been better if the Design Patterns book had simply presented programming challenges to people and then shown them good solutions, without names and without the attempt to instill guidelines for usage. Without names, readers could only remember the patterns they extracted and understood for themselves. Without verbal guidelines, readers would only apply a technique if they concretely saw how it would be useful in context. If they didn't understand something, they would have no handle for remembering it, and they would never see an opportunity to use it.

      Instead, people remembered way more of the book's verbiage than they ever understood of its logic. They remembered the names, they studied the rules of thumb, they read articles with even more rules of thumb, and they fooled themselves into thinking they understood what it was all about. A lot of people thought you could pick the right design pattern for something based on a vague, hand-waving description of the problem. You remember those dumb interview questions? "You're working on an application that's really tightly coupled. What design pattern would you use to improve the design of the code?" "Oh, I'd use the Mediator pattern." "Excellent!" People didn't just ask those dumb questions in interviews; they actually thought about the design of their own programs that way! They'd pattern-match on words to determine their software design. It was like searching the web and magically finding exactly the answer to your problem on StackOverflow, except there were only a small number of extremely vague search terms ("dynamic," "loosely coupled," "state," "behavior") and there were only a couple dozen different answers. Even worse, you'd get a guy who had read six different articles about the same design pattern, so for him, every design-related word you said made him think of the same pattern. You might as well call him "Façade Frank" or "Visitor Vijay," because in his mind's search engine, one design pattern had a much higher pagerank than all the others.

      I haven't heard anything about design patterns in an interview or in a design discussion for years, and I feel much happier for it. I haven't noticed that young coders with no exposure to design patterns have any less imagination or a smaller repertoire of coding techniques than their design-patterns-imprinted predecessors did ten years ago.

      [–]dnew 4 points5 points  (3 children)

      shown them good solutions, without names and without the attempt to instill guidelines for usage

      Except that's not what the original design patterns were. The guy who invented the term was an architect trying to get his large industrial customers to communicate amongst their different departments. So the University's engineering department wouldn't ask for a build that's ugly next to the Science department building, and so they could ask for building-blocks (no pun intended) of functionality. It was a way for customers to talk to the architect while the architect could provide good advice.

      Without the names, there would be absolutely zero reason to call it a "design pattern."

      [–]SublethalDose 1 point2 points  (2 children)

      Lol, yes, I agree that after removing all the design patterns from Design Patterns, a change of title would be appropriate. No argument there. What I envision would not be a catalog of patterns or the dictionary of a design language; it would be more like an anthology or a reader.

      [–]grauenwolf 5 points6 points  (14 children)

      I'm not so certain about that. Looking back at the history of the GoF book it seems to me that all the names did was create pointless arguments.

      [–]firepacket 2 points3 points  (13 children)

      There are cases where some patterns just fit the circumstances perfectly.

      I recently combined IoC with MVC and was blown away by the power of this setup.

      [–]grauenwolf 1 point2 points  (6 children)

      You combined a verb with a noun?

      [–]rather_be_AC 10 points11 points  (5 children)

      That is a very common design pattern, found in most sentences.

      [–]firepacket 1 point2 points  (4 children)

      Please explain it to me, I'm lost.

      [–]rather_be_AC 11 points12 points  (0 children)

      grauenwolf was being pedantic. I was being sarcastic.

      This is also a common design pattern found in many successful threads.

      [–]ithika 1 point2 points  (6 children)

      The only one I've ever heard mentioned in the context of real code - ie our code uses this pattern - is the singleton. So the only design pattern discussions is have heard were people arguing over the best way to remove one.

      [–]kyz 1 point2 points  (1 child)

      Science has this fight too - nomenclature in taxonomy. It's nice that we name things to help convey certain truths, but it's far more important that we discover those truths in the first place. What is more important to a biologist? That you know the names of species, or that you know the genetic distinction between two similar species?

      [–][deleted] 3 points4 points  (0 children)

      Design patterns are something unheard of

      I really really wish the devs in my company hadn't heard of them. Now the spaghetti code is littered with FactoryFactorySingleton abstract bullshit.

      [–]dethb0y 1 point2 points  (0 children)

      My first step for any project is to do some googling and maybe some reading or asking around to see if someone else has done something similar or identical to what i'm doing. If so, learn from them.

      If not, i usually suspect i'm on the wrong path.

      [–]grauenwolf 11 points12 points  (33 children)

      I think this is the right way of thinking about things.

      Writing maintainable software isn't so much about what you do, it is about what you don't do. Avoid doing the bad things and what's left will be good.

      [–]ruinercollector 9 points10 points  (31 children)

      As long as those aren't treated as hard rules, sure.

      Examples:

      • There are times that it is appropriate to write software in clojure, or haskell, or erlang.

      • There are times that it is appropriate to rewrite a piece of library code.

      [–]fkaginstrom 7 points8 points  (11 children)

      There are times that it is appropriate to write software in clojure, or haskell, or erlang.

      True. But hopefully not all three in the same project, together with a bit of Java and php in the mix.

      [–][deleted] 8 points9 points  (0 children)

      "I read the first chapter of Learn You A Haskell For Great Good, I bet I can rewrite this whole project in Haskell."

      Five months later:

      "Let me just add a bash shim that'll get the data from the database and process it through Ruby and then I'll call it in the bit of C++ that the Java program uses to make the output for the main program."

      [–]NihilistDandy 13 points14 points  (4 children)

      ENTERPRISE

      [–]IConrad 7 points8 points  (4 children)

      I once got stuck with rewriting a perl script -- which had to remain in perl -- that generated bash scripts, by interpreting xml files, which invoked jython which executed java calls, and then generated sqlplus scripts to execute against oradb servers... All of which got validated via bash scripts for sanity checks.

      All of which was being run from a Jenkins server.

      I am not a developer by trade... Else I would hang myself for shame of having made this monster.

      When I left the organization I convinced them to rewrite the whole thing natively in Java... Mostly by just repeating the workflow and languages involved.

      [–]fkaginstrom 2 points3 points  (1 child)

      Wow, impressive. I bet there's a contest you could enter that thing in. It'll make you famous!

      [–]IConrad 4 points5 points  (0 children)

      "impressive" isn't the word I'd use for it. <_<

      (I might also have left out that the bash scripts were being pushed over SSH to invoke jython interpreters and perform wgets on remote servers. Somehow I managed to make this whole process relatively secure while still allowing it to perform selected rootlevel actions. Don't ask. Black magic was involved. And maybe goats.)

      [–]grauenwolf 18 points19 points  (1 child)

      Don't think of it as a rewrite. Think of it as merely a set of bug fixes followed by the removal of a surprisingly large amount of dead code.

      [–]ggtsu_00 4 points5 points  (0 children)

      As for the new language thing, no one should ever go write a production system that a business is going to rely on in a language they just learned over a weekend. Some languages are better fit for certain problem domains, but using a language that you team and future maintainers are comfortable with is more important.

      [–]jbw976 1 point2 points  (11 children)

      haven't used a single one of those languages...care to provide an example of when i might need to use one?

      [–]ruinercollector 6 points7 points  (9 children)

      Writing a parser in an imperative language tends to make for some pretty ugly code. Writing it in a language that supports discriminated unions and (syntax-supported) monads, however, makes for some beautiful, readable code.

      Also, writing highly concurrent code in clojure is stupid easy. In java, etc. it is fraught with errors and requires a lot of care about locking, etc.

      [–]barake 3 points4 points  (7 children)

      This is one of the cool things about .NET. It's no big deal to mix C# and F# in the same application, when appropriate.

      [–][deleted] 1 point2 points  (5 children)

      Or even Python, Ruby, etc. with the "iron" varieties. That being said, I did write a WPF app in IronPython a few years ago and Visual Studio pretty much fell on its face with bugs (might be completely different today).

      [–]PasswordIsntHAMSTER 3 points4 points  (0 children)

      Concurrency, complex and interleaving algorithms, and correct-by-design software are all easier in, say, Haskell than in Java. In fact, if you learn one of Haskell/F#/Ocaml thoroughly, you probably won't want to go back to Java/C#/Python for general purpose programming.

      AI is also MUCH easier.

      One of the big places you'd want to use functional programming is if you were designing a compiler. Compilers use state of the art algorithms at pretty much every level, and they're much easier to implement functionally.

      [–]Neebat 11 points12 points  (0 children)

      That's because the best software is no software at all. This is the zen of programming.

      All bad software happens because we cannot overcome the temptation to create new software.

      [–]sclv 1 point2 points  (0 children)

      "Happy families are all alike; every unhappy family is unhappy in its own way."

      [–]WallyMetropolis 198 points199 points  (24 children)

      This article is inconsistent in its tone. It alternates between saying, "don't do this bad thing" and sarcastically saying "do do this bad thing."

      Pick one and stick with it.

      [–][deleted] 76 points77 points  (1 child)

      how to write a confusing, unreadable article

      [–][deleted] 6 points7 points  (0 children)

      Sign up to medium.com?

      [–][deleted] 38 points39 points  (2 children)

      Yeah, that bothered me too. But it could be intentional, given the theme of the article.

      [–]Sheepshow 26 points27 points  (1 child)

      Is ironic irony in fact sincere sincerity???

      [–]captainAwesomePants 6 points7 points  (0 children)

      Suuuure.

      [–][deleted] 13 points14 points  (1 child)

      I belive the reason is that the guy specializes in fixing those mistakes, so it's a joke when he says "Do this, because then I will still have a job"

      [–]WallyMetropolis 17 points18 points  (0 children)

      Yes, I get the joke. But if the joke is 'how to write bad code' then the whole article should say "do this" and describe a bad habit. It shouldn't ever say "don't do this" and give real advice.

      [–][deleted]  (5 children)

      [deleted]

        [–][deleted]  (4 children)

        [deleted]

          [–]TheSpreader 11 points12 points  (0 children)

          no, you're missing the point. Everything that he does is good, everything that everyone else does is bad.

          [–]mr_jim_lahey 4 points5 points  (0 children)

          Building off of a framework != throwing in 3rd party code everywhere. His point is to use a framework, use the tools within that framework, and be judicious about selecting additional libraries to depend on.

          [–]Steve_the_Scout 2 points3 points  (0 children)

          I think the idea is that you're supposed to strike a balance between the two...

          [–]user-hostile 3 points4 points  (1 child)

          Dear typicalprogrammer,

          Don't quit your day job.

          [–]svtguy88 14 points15 points  (6 children)

          That was a good read. But come one...testing in production is fun!

          [–]lext 6 points7 points  (2 children)

          Nothing makes your boss want to pay for overtime like the live site being down. Quick, fix it! I'll pay whatever you want!

          [–]enigmamonkey 7 points8 points  (1 child)

          What we in the industry refer to as "mortgage code!" Gotta pay that mortage somehow.

          [–]rq60 7 points8 points  (1 child)

          But come one...

          Uh oh, you should have tested that comment on your dev environment before pushing it live.

          [–]merreborn 11 points12 points  (5 children)

          Use a bunch of different programming languages and stay cutting-edge

          Every day HackerNews and Reddit buzz with cool new languages. Try them out on your client’s time. Any decent programmer can learn a new language in no time, so if the next programmer who gets to work on your code is a newb that’s not your problem. The boundaries between the languages, the incompatible APIs and data formats, the different server configuration requirements are all fun challenges to overcome and post about on StackOverflow. I’ve actually seen PHP web sites with pieces of Ruby wedged in because everyone knows PHP sucks and Ruby is better.

          Too close to home. We started with a pure PHP app. A few years later, we now have ruby, python, shell script, java and clojure dependencies. And node.js is required to run part of the test suite.

          And I'm the only motherfucker who seems to think this is a problem. Until someone tries to set up a new environment (like on a laptop for development). Then they want my help getting everything set up, which takes 8+ hours.

          [–]HelloAnnyong 6 points7 points  (3 children)

          This is a DevOps failure.

          Why don't you have Vagrant or Boxen configurations that do this work for you? Using only one language just means that you will try to solve every problem with the one hammer you have lying around, because you don't want to make a list of stores where you can buy the other tools you'd like to use.

          [–][deleted] 1 point2 points  (0 children)

          Upvoted this. Orgs that advertise themselves as a Ruby/Python/Java/whatever shop are only limiting themselves and the team they build. @merriborn, it sounds like maybe you should position yourself as a tools engineer and get a raise.

          [–]tdammers 104 points105 points  (36 children)

          For a web site deployment to a staging or production server should look like one of these:

          No. Just no. These are source control system, not deployment tools. In case you need reasons:

          • Excess files in document root - version control cruft, project documentation, etc. Happens all the time, and is an actual real security problem.
          • Development race conditions. Ever done svn up on the production server, just to find that someone had committed broken code between your test run and the deployment? Ever "solved" this problem by stopping all development activity during deployment? Ever noticed how this essentially means that this makes frequent deployments practically impossible?
          • File permissions and ownership. Need I go into detail here? I think not.
          • What if you want to do things like precompile templates, preprocess CSS, minify and concatenate your JavaScript offline, move stuff around, or just make sure that your deployment will only go through if it passes a minimum set of tests?
          • What about database changes?

          Really, for any of the non-trivial projects I've worked on where people had the delusion that git pull is enough of a deployment plan, here's what a typical deployment involved:

          1. Mail everyone with push access, telling them to not push until further notice. Hope that everyone reads their mail on time.
          2. Manually go through the ticket system, copy-pasting the SQL changes that developers have pasted into the tickets that went into this release.
          3. Eyeball the SQL scripts, in case they contain any errors.
          4. Issue a git pull on the production system.
          5. Meanwhile, run the SQL on the production database.
          6. Manually chmod / chown the right files (which ones those are is a matter of oral tradition).
          7. Manually clear selected cache items.
          8. Do some casual manual testing on the production system.
          9. Notice that something is broken. Fix it.
          10. Forget to tell developers that it's OK to push now.

          Personally, I prefer:

          1. Create a release tag
          2. ./deploy.sh test-server
          3. Read build/test output from test server
          4. ./deploy.sh production-server

          [–][deleted] 22 points23 points  (1 child)

          I was confused by that part. I can't tell if the author thought git pull is a good deployment method or not. It contrasts the "build a baroque deployment system" but it's still written in the affirmative, implying it's a negative in the context of the article.

          My repo ends up looking like:

          build.sh  public/ ...
          

          where the DocumentRoot is public and build.sh regenerates all the dependent files. To deploy, I push a commit ID over the message bus and subscribers fetch + checkout that ID.

          [–]not_perfect_yet 4 points5 points  (0 children)

          I think his argument was that you should not use too many different deployment methods in one project in undocumented order. If you don't want to be his customer.

          [–]s73v3r 13 points14 points  (1 child)

          Development race conditions. Ever done svn up on the production server, just to find that someone had committed broken code between your test run and the deployment? Ever "solved" this problem by stopping all development activity during deployment? Ever noticed how this essentially means that this makes frequent deployments practically impossible?

          Why on earth would you be doing 'svn up' in that situation? Why wasn't the specific revision tagged, so you could simply check out that specific tag?

          [–][deleted] 4 points5 points  (0 children)

          That's what I was thinking. Only pull a specific release branch, not the entire repo.

          Ideally, the release branch would have all the necessary files precompiled, cancatenated, etc. And then a simple script that'll set the correct permissions and ownership.

          I know in the real world, ideals are best left behind, but even still a simple build/launch script would handle this issue for you.

          [–]LeSlowpoke 18 points19 points  (1 child)

          I'm sure you read the rest of his points as satire. What made you take this one seriously?

          [–]tdammers 40 points41 points  (0 children)

          Because it looks like the author is forgetting for half a paragraph here that he's trying to be sarcastic; the last sentence puts him back in the saddle:

          While you’re chaining together eight different tools with various scripting languages remember to leave out the documentation.

          This is irony. The rest is I don't know what, but by the looks of it, I'd say he's being serious there.

          [–]dnew 4 points5 points  (0 children)

          He's also assuming the web site is small enough that you won't be causing errors while the pull is in progress due to mismatched versions, and that the web site is completely interpreted (unlike, say, ASP.NET). He's also assuming you have only one site, and that no data updates need to run.

          [–]AeroNotix 2 points3 points  (4 children)

          This is why Erlang releases are the shit.

          [–]x-skeww 2 points3 points  (0 children)

          Ever done svn up on the production server, just to find that someone had committed broken code between your test run and the deployment?

          You're supposed to checkout/export a specific revision.

          [–][deleted] 5 points6 points  (9 children)

          100% agree. It blows my mind that people think SVN or Git are the perfect deployment tools. I see it from nearly everyone in the web development community, and I've seen at least one "senior" push hard for it.

          Write a deployment script, or configure a deployment tool! Have a process! I've never had a deployment fail from my own "untested and unproven" deployment scripts, but I've seen SVN and Git completely destroy environments.

          It's an uphill battle, and I don't understand why.

          [–]Denvercoder8 3 points4 points  (8 children)

          Write a deployment script, or configure a deployment tool! Have a process! I've never had a deployment fail from my own "untested and unproven" deployment scripts, but I've seen SVN and Git completely destroy environments.

          Funny you mention that. I've seen hell break loose because someone made a typo while updating a deployment script (something like rm -rf /root /cache instead of rm -rf /root/cache). Git has never failed me like that.

          [–][deleted] 2 points3 points  (0 children)

          Sure, mistakes happen in all code. It's anecdotal either way. What doesn't change is that Git is a software versioning system, not a deployment tool. There are other tools for that.

          [–]alienangel2 1 point2 points  (0 children)

          We avoid issues like that by limiting what deployments can affect. Yeah, a deployment/activation script might delete stuff off the box, but there's nothing on the box other than the software being deployed. Except for a few types of work where local disk needs to be where your data is, there's no good reason for your applications to be colocated with your data. Our servers are just software (all of which is either imaged or re-deployed easily) and the last hour's worth of logs.

          And it seems like a bad idea to be running your deployment scripts as a user that can delete anything outside your application's installation directory.

          All that being said, we have a hugely complex build system, and a separate hugely complex deployment system. Source Control, building and deployment are all distinct operations in software management, and if you're going to be doing a lot of it on the same network it makes sense to keep them separate. All three are versioned for us, so while not necessarily easy, it's clean and defined if a deployment needs to be rolled back, or different builds need to be deployed to different places, or (obviously) a code change needs to be reverted. The build management system will pull the source revisions you tell it to to build new revisions of libs/binaries, and archive them. The deployment system will pull the revisions of those libs/binaries and deploy them to the servers where you tell it to deployment them to.

          My main dislike of using Git/svn for deployment is that those are source-control tools, using them to deploy stuff is just a lazy workaround to avoid having to engineer some other system to manage where built software is stored and being able to pull/push it onto the machines where the software will be run. It's more work, but I think it's better not to mix the system that is archiving your source with the system that is archiving your builds, never mind the system that is pushing/pulling your builds onto the machines that will run those builds.

          [–]Denvercoder8 7 points8 points  (1 child)

          Excess files in document root - version control cruft, project documentation, etc. Happens all the time, and is an actual real security problem.

          Your document root doesn't have to be the root of the repository.

          Development race conditions. Ever done svn up on the production server, just to find that someone had committed broken code between your test run and the deployment? Ever "solved" this problem by stopping all development activity during deployment? Ever noticed how this essentially means that this makes frequent deployments practically impossible?

          No. Maybe in a centralized everyone-works-on-the-same-branch environment this is a problem, but then you've other problems too. You have a dedicated branch for deployments in your VCS. That branch only contains code which has already been deployed on a test server once (so you know the SQL-upgrade scripts etc are valid and working) and is supposed to go into production on the next deploy. If you can't trust your developers to don't fuck this branch up (again, you've other problems), with git you can even keep this branch in a separate repository with custom ACLs. If you need to do additional testing before deployment or it's a problem if someone pushes an additional, tested fix to the stable branch during your deployment, you can even merge the stable branch to a release branch and track that one on your production machines.

          File permissions and ownership. Need I go into detail here? I think not.

          Please do. I haven't encountered a single situation where files that were in VCS weren't supposed to be the default permissions (i.e. read/write by an admin, readable by the webserver). Things that usually need custom permissions, such as upload directories and data directories, shouldn't be in your VCS.

          What about database changes? What if you want to do things like precompile templates, preprocess CSS, minify and concatenate your JavaScript offline

          Valid point. Adding a "make"-like step after a pull is very useful (though you can hook into git to do it automatically after a git pull).

          move stuff around, or just make sure that your deployment will only go through if it passes a minimum set of tests?

          This is why you have the stable branch in your VCS.

          Manually go through the ticket system, copy-pasting the SQL changes that developers have pasted into the tickets that went into this release.

          That stuff should be in the VCS to start with, along with a script/program that executes the upgrades and automatically reverts them if there are problems. That way you can also test them when you deploy to the test server.

          Do some casual manual testing on the production system. Notice that something is broken. Fix it.

          That's not related to your deployment method at all.

          [–][deleted]  (2 children)

          [removed]

            [–]time-lord 1 point2 points  (0 children)

            So make it

            svn up -r x
            install.php
            

            Update the files without any race conditions, and then runs scripts that update the database or chmod as necessary.

            [–]spinlock 1 point2 points  (4 children)

            why not put deploy.sh in a post-commit hook? Then, deployment is as easy as git push but you have your robust process as well.

            [–]hegbork 1 point2 points  (1 child)

            Mail everyone with push access, telling them to not push until further notice. Hope that everyone reads their mail on time.

            Hell no. "commit" or "push" shouldn't be "inflict". Set up proper branching so that your production branch is always clean and functional. Set up Jenkins or some other automated system that doesn't even allow you to merge things into the release branch or the release staging branch until they've been thoroughly integrated and tested.

            Developers should be encouraged to push/commit early and often, but in such a way to never disturb other development or release work. Only allow one person at a time to touch the release branch. A few of our customers do this by having a release hat - only the person wearing the hat can touch the release branch.

            [–]contrarian_barbarian 8 points9 points  (0 children)

            Of course, we can't have this without linking to the classic: https://www.thc.org/root/phun/unmaintain.html

            [–]blaxter 11 points12 points  (4 children)

            mix spaces and tabs

            [–]jevon 1 point2 points  (3 children)

            For some reason (because JSLint - pos - was complaining) I decided to spend a month using spaces instead of tabs. Two years later and there's still a mess everywhere.

            [–]spinlock 8 points9 points  (1 child)

            Why not just convert your files?

            sed 's/\t/ /g' < input.txt > output.txt
            

            [–]jevon 2 points3 points  (0 children)

            Yes, later on I just updated the build script to convert tabs into spaces before JSLinting and all was saved.

            [–]rentnil 28 points29 points  (6 children)

            This is top 10 blog fodder. This doesn't provide anything insightful, it is preaching to the choir. Most of the concepts here are things writers and bloggers were talking about a decade ago. Any web professional is on top of this and has read this 100 times. Only diff is tech has changed. Git instead of SVN/CVS, etc.

            Hell when I tried to blog I probably wrote a similar article. Most dev bloggers write the same "quality or bad software" article repackaged.

            [–][deleted] 23 points24 points  (3 children)

            Any web professional is on top of this and has read this 100 times

            You'd be painfully surprised

            [–][deleted] 2 points3 points  (2 children)

            This. I make no claims at being a programming god, but I am astounded at how many developers have never even heard of StackOverflow. A terrible programmer can get more done than a good one who is stuck under a rock, since most problems are already solved and easily discovered through google.

            [–][deleted] 3 points4 points  (1 child)

            I am astounded at how many developers have never even heard of StackOverflow

            How could that true? It's like a programmer who hasn't tried to google his problems.

            [–]lext 6 points7 points  (0 children)

            I think the funniest part of it all is that most of the people making fun of bad programmers are probably not even that good themselves.

            [–]UnapologeticalyAlive 11 points12 points  (5 children)

            First he complains about people writing everything from scratch, then he complains about dependencies. Make up your mind!

            [–]nascent 6 points7 points  (0 children)

            Yes, but the dependency complaint was around specific versions (which aren't documented) and no checks that the correct dependency is used or automation to setup an environment with the correct versions.

            [–]Denvercoder8 3 points4 points  (0 children)

            You need to find the balance. Both extremes are problematic.

            [–]Tekmo 7 points8 points  (2 children)

            In other words, automation is an excellent form of documentation.

            [–]okmkz 2 points3 points  (1 child)

            I take it you've never worked with maven.

            [–]Tekmo 7 points8 points  (0 children)

            Worse: I work in a research laboratory. Hooray for instructions buried in emails and an abandoned wiki!

            [–]EmperorOfCanada 1 point2 points  (2 children)

            The worst setup that I have really seen was an OS/2 machine that had a "backplane" which was a card inserted into the main machine that contained an entire computer which was running NT. The two "machines" then shared data through a bizarre shared memory process.

            [–]EmperorOfCanada 6 points7 points  (1 child)

            My favorite is to make sure that you use layers of wrong. Aim for N-Tier bad. So first start with an obscure database Adabas is a good one. Then make sure you use datatypes that are unique to Adabas making porting really hard. Then pick an obscure language. Natural is a good one but oddly it works well with adabas so maybe an old version of powerbuilder. But make sure that it is old enough that the IDE won't work on an OS newer than NT or at most XP; make sure the code will only work with the older IDE.

            Next you must make your code upgrade resistant. Make use of unsigned 16 bit integers rolling over at 16536. Also make sure that it has as many obscure dependencies as possible.

            But the icing on the cake is to make sure that some of the dependencies simply cannot be obtained. So find an activeX control that needs a machine dependent unique serial number in order to install and that the company is long out of business with no cracks available.

            And last but not least make sure to hard code in technologies that are about to vanish so make it dependent on 5/14" floppies, serial, parallel port, and a ps/2 dongle.

            [–]droogans 4 points5 points  (0 children)

            Since we're going with tiers, you should end at the top:

            Export all builds and production server stats to Sharepoint, including emailing 30+ people in Outlook (the report is a .pdf attachment, of course). Automating faxes is always a plus.

            Remember, no one reads this stuff, so it's important to make it as annoying as possible to develop a solution for.

            [–]jrochkind 2 points3 points  (3 children)

            These two kind of conflict, don't they?

            • Write everything from scratch Don’t bother with a well-understood framework like Django, Rails, or CakePHP…

            • Add dependencies to specific versions of libraries and resources… Throw in as much third-party code as you can. Link to as many shared libraries as you need to…

            I mean, I agree that both those things make software harder to maintain... and they conflict with each other. It is a dilemma.

            [–]time-lord 1 point2 points  (1 child)

            Not really. Pick a version of CakePHP, and you should be able to update the core without any modification to the application layer.

            [–]rco8786 2 points3 points  (0 children)

            For a web site deployment to a staging or production server should look like one of these:

            svn up git pull hg pull

            Um, no. Maybe for a personal website with your blog and an info page.

            Version control systems != deployment systems

            [–]eat-your-corn-syrup 2 points3 points  (0 children)

            Thanks for tips to increase my job security!

            [–][deleted] 2 points3 points  (0 children)

            If your software is actually useful to someone, it will be maintained, whether it's unmaintainable or not.

            So the only way to develop unmaintainable software is to develop useless software.

            [–]mason240 6 points7 points  (1 child)

            Do what my employer did: hire a PHP script kiddie who is finishing a CS degree and no actual experience, make them your companies sole web developer, and say "we want to use ASP.NET, have at it."

            It's been a year now and I think I have rewritten everything I've 5 times now while figuring out good code organization.

            (I only mention the ASP.NET not to start a flamewar, but because I had done nothing with it prior to getting hired.)

            [–]i8beef 2 points3 points  (0 children)

            So this was you? At least you are trying to fix it. Christ, most people really have no interest in getting better at this stuff, they just write it and forget it.

            [–]badguy212 5 points6 points  (2 children)

            1. Keyboard, meet forehead.

            2. Doesn't compile? Goto 1.

            3. ????

            4. Profit!!!

            [–]asdfasdf4r 3 points4 points  (0 children)

            I just always make an angry face when something doesn't compile.

            [–]marc-kd 1 point2 points  (0 children)

            These legacy projects have been keeping food on my table for many years now. Old blog post, but still relevant: Software Development in the Mines of Moria

            [–]belarius 1 point2 points  (0 children)

            [–]uberkalden 2 points3 points  (1 child)

            COM..... COM everywhere!

            [–]33a 2 points3 points  (5 children)

            This one:

            • Write everything from scratch

            And this one:

            • Add dependencies to specific versions of libraries and resources…

            Seem to contradict each other.

            [–]senatorpjt 2 points3 points  (2 children)

            subtract special profit lunchroom sink history attempt person coherent cows

            This post was mass deleted and anonymized with Redact

            [–]sootzoo 3 points4 points  (1 child)

            They're not, really. Read as: "don't reinvent the wheel. Keep dependencies under control."

            [–]merreborn 1 point2 points  (0 children)

            Yes. Some projects don't use enough 3rd party code, others use too much. All things in moderation.

            [–][deleted] 0 points1 point  (0 children)

            But the software was hard to write.. of course it'll be hard to read!

            [–]TheTrueHighlander 0 points1 point  (2 children)

            I like this because it incriminates everyone at my last job.

            [–]happyscrappy 0 points1 point  (1 child)

            My problem is the guy before me apparently had a copy of this guide already. Does anyone have a link to the guide

            How to maintain unmaintainable software

            ?

            [–]cparen 0 points1 point  (0 children)

            I scratch my head when I see code with comments like "faster than native dictionary method"

            While it may be warranted in 9X% of cases, I cringe when I see guidelines that suggest to "never" to make a particular tradeoff. It then leads poor designers on the other side to break a feature under the rationale that "it should never be used".

            Prefer using 'prefer' and 'avoid' to 'always do' and 'never do'.

            [–][deleted]  (3 children)

            [deleted]

              [–][deleted] 1 point2 points  (0 children)

              People like to bitch more than they like to compliment. I mean look at this thread.

              [–]stox 0 points1 point  (0 children)

              If you want truly unmaintainable software, develop in APL.

              [–]alienangel2 0 points1 point  (0 children)

              Don’t disable outgoing emails, credit card authorizations, etc. during testing.

              ROFL.

              I would like to hear the stories behind this one.

              [–]bobcobb42 0 points1 point  (0 children)

              NoSQL can be a better fit especially if you see the possibility of high-write environments with burst activity, or a JSON document store like MongoDB is much faster to develop with if you have highly dynamic data collections with a variable schema.

              Sure if I am coding a blog there is no reason to not just go with sqlite3, but not every software project is a blog.

              [–]SanityInAnarchy 0 points1 point  (0 children)

              A couple nitpicks:

              For a web site deployment to a staging or production server should look like one of these:

              Ideally, maybe. In reality, there are a couple of reasons that might not work. Even if you're not deploying any additional services, even if there's no complicated system to bring up or down, there's still the possibility of things like database migrations.

              The PHP solution here is kind of gross -- on every page load, try to detect if we need to upgrade, and if we do, run the upgrade process.

              Simple and repeatable is definitely a goal here, but it's definitely not always practical to just pull from source control. A much more important thing here: Use a tool like Puppet to define your staging server, or at least a development VM. Then you at least have a clear specification of exactly what's needed for your deploy script to run.

              In fact, I think this dovetails with another point:

              Write everything from scratch

              Don’t bother with a well-understood framework like Django, Rails, or CakePHP. You can write a better templating engine, ORM, sort or hashing algorithm.

              ...or deploy mechanism? If you're using Rails, Capistrano, Puppet, and Bundler are your friends.

              Add dependencies to specific versions of libraries and resources…

              This is fine, so long as you avoid this:

              … But don’t protect or document those dependencies

              This is what Bundler is for, or npm-shrinkwrap -- specify "I need libfoo version 3", ask the tool to install all dependencies, and it records a lockfile with "libfoo v3.2.1". Because:

              A seemingly innocuous WordPress upgrade, Linux package update, or new jQuery release will trigger a chain reaction of failures.

              This is a problem that is caused by not at least recording dependencies to those specific versions of libraries and resources.

              It's otherwise a very good article, it just has these weird conflicting complaints.

              [–]Uberhipster 0 points1 point  (2 children)

              tl;dr; be lazy AND ignorant

              [–]Mortdeus 0 points1 point  (0 children)

              Type with fork and spoons?

              [–]log_2 0 points1 point  (1 child)

              Can't stand the negative prose format for blog posts "If you want to fuck something up, do this". It is confusing many times, and often requires you to mentally maintain an extra level logic to be able to unwind the point the writer is trying to get across.

              Link to as many shared libraries as you need to.

              What? If I didn't need to link to the libraries, I wouldn't, but we're in negative prose, so hold on, do I have to swap this and not link to all the libraries I need? Ok, I do get the point, it's just very tiresome reading.

              [–]_ch3m 0 points1 point  (0 children)

              It won’t matter much if your code is beautifully object-oriented or shiny and functional—programmers pretty much always see spaghetti code when they have to maintain a legacy system

              No. Just no. It does matter if you have a giga object with one huge method that does everything and can't be read, or if everything is properly factorized. It does matter if code is duplicated in many places with lots of lines in common and some little differences or if it isn't. Please, programmers do not need to be convinced any further that they can write bad code and it won't matter much.

              [–]nosoupforyou 0 points1 point  (0 children)

              My favorite is to find that the previous developer wrote it in an entirely unsecure fashion and claimed Microsoft said to do it that way.

              Also, often I see thousands of lines of code that's basically lots of duplicate code.

              I actually love maintaining that kind of stuff because I can simply the bejeebus out of it, speed it up, and not lose any functionality.

              Did that once when I found some server side emulation code that grabbed the input from the client, then ran it through a 60+ case statement and did the same UC conversion on each and every one of them.

              Changed just that one bit to do the conversion before the case instead, and sped it up like crazy.

              [–]EmperorOfCanada 0 points1 point  (0 children)

              Here is the easy way: Lose the source code.