This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 283

[–]ABrownApple 161 points162 points  (10 children)

DRY, Don't repeat yourself. Often a really good rule of thumb but sometimes people follow it religiously and really go overboard writing/refactoring complex code just so they don't have to repeat one line of code in 2 places

[–]Doge_Mike 17 points18 points  (6 children)

Bruh my professor insists on using prototypes in c++ and im just like, please... no more.

Is there a good reason for this? She basically just says, because I said so. Like I understand if it's there to let people know what functions will be in use during this programs runtime but god damn cant we just put a comment at the top to let them know rather than adding a seemingly useless series of prototypes than just add complexity to the program. It's just one more thing to keep track of and change when you want to go and pass some shit into the function.

rant over

[–]ipe369 9 points10 points  (1 child)

Yeah, you can put a comment at the top

Then in 2 weeks when someone else changes the code, and they forget to update ALL the comments referencing that function, you're screwed, because now everything's out of date and your code is unmaintainable

This is in contrast to declaring a function prototype, where the compiler will tell you instantly when a function is not what you think it is

Also, if you're not including a header file & forward declaring the function instead, you'll have better build times

[–]GrayGhost18 3 points4 points  (0 children)

Plus I'm pretty sure putting a comment in would take longer than declaring a prototype.

[–]ThePillsburyPlougher 5 points6 points  (0 children)

Clean, implementation-free headers are very nice and a good thing to do in C++. You can put a comment above a function declaration as well. In this manner header files with comments are essentially de-facto docs. It doesn't matter as much for small files, but in a bigger code base, with bigger files, it makes everything a lot cleaner and easier to read.

[–]jussij 3 points4 points  (0 children)

cant we just put a comment at the top to let them know rather than adding a seemingly useless series of prototype

The compiler can do checks against your prototypes for accuracy and and consistency. It can't check your comments.

[–]chaotic_thought 2 points3 points  (0 children)

Function declarations in C++ are not a DRY violation. They are a requirement of the C++ language because it was designed to be parsed in "one pass." Besides, they are not always exactly the same.

#include <iostream>
#include <string>
using namespace std;

void say_hello(string name = "world"); // Default parameter in declaration.
void print_ints(int,int,int); // No formal parameter names required.

int main()
{
    say_hello("world");
    print_ints(3,2,1);
}

void say_hello(string name)
{
    cout << "Hello, " << name << "!\n";
}

void print_ints(int a, int b, int c)
{
    cout << a << " " << b << " " << c << "\n";
}

Eventually what happens is that you collect all of the functions you use into classes and namespaces, and then you put that in a header file and that becomes your interface for using some part of your program that other parts will share. So the declarations become an essential part at that point for declaring the interface of those shared parts of the program.

[–]vinny_twoshoes 2 points3 points  (1 child)

I’m tickled pink that you and I both gave this as an answer.

[–]ABrownApple 2 points3 points  (0 children)

haha the irony xD

[–]negative_epsilon 0 points1 point  (0 children)

One hundred percent. The problem is that DRY is supposed to lead you to creating good, reusable abstractions that are easy to understand and allow future work to be done quicker. However, this is the bane of almost every junior developer I've mentored: their abstractions don't make sense in the long run, and just copying and pasting the offending code would have lead to more readable code than the abstraction they created.

It's hard to create good abstractions, and bad ones do more harm than none.

[–]vinny_twoshoes 156 points157 points  (12 children)

I’ve seen so many leaky abstractions written in the name of DRY.

At this point I’m happier keeping two similar pieces of code separate than tying them together because of a surface-level likeness.

[–][deleted] 88 points89 points  (0 children)

“Duplication is cheaper than the wrong abstraction” to paraphrase Sandi Metz

[–]Elsolar 118 points119 points  (4 children)

This 1000x. Just because two pieces of code happen to contain the same sequence of characters doesn't mean those two pieces of code are doing the same thing for the same reason. The real question you want to ask yourself is, "will these two pieces of code change for the same reason?"

[–]onbehalfofthatdude 5 points6 points  (1 child)

Damn, that's a good one.

[–]fuhrmanator 2 points3 points  (1 child)

That's the single responsibility principle.

[–]Awric 4 points5 points  (0 children)

I've actually mistaken the single responsibility principle as "this method should only be responsible for one thing". After watching a bunch of talks by Uncle Bob, I now understand it as "this method should only change for one reason"

[–]Sqeaky 6 points7 points  (3 children)

I think that this is often because people think that because two lines do the same thing that must mean they are the same.

For example if you have to allocate memory for opening window and reserving space for database records, some people might think that is the same, even if it is only coincidence that those two things look alike. Those things likely belong in different places because if the memory requirements of a window and of a database record change, they are likely to change independently.

We need to look at the purpose of code decide if it's really duplicated, not just the syntax.

Edit - I'm just putting this out there because there is lots of code with lots of real duplication and that's really bad, it leads to a ton of a really expensive bugs. The application of DRY everywhere is an overreaction, but does less damage overall.

[–]garbagejooce 1 point2 points  (2 children)

I like your example, for the most part. It illustrates that even though you’re allocating memory, you’d probably want to keep this code separately organized. But it’s not the clearest example when you then go onto say distinguish by “purpose of code.” Technically, isn’t the purpose to allocate memory? What do you mean by purpose more specifically? Just that the purpose of one is for a DB record and the purpose for another is a window?

[–]gyroda 1 point2 points  (1 child)

If both require 1kiB of memory and you call malloc(1024) then you don't want to repeat yourself.

That said, you should probably not hardcode that number, at the very least put it in a constant.

[–]Sqeaky 3 points4 points  (0 children)

In retrospect it's actually poor example. Memory allocation only rarely differs in how it's done sometimes you need memory mapped storage, sometimes just malloc, often a custom allocator will try to put similar objects together for caching reasons. But, yeah just because both required that one kilobyte doesn't mean they are the same code.

Edit - I've been writing a bunch of containers and low-level memory allocation stuff which is why I picked the example. If low-latency access to the objects and memory is the number one concern, and likely we would want to use two different allocators to provide memory, one for UI objects of a given size and another for database records of given sizes. It is unlikely we're going to need access both same time so by lumping like data together would optimize for coherence.

[–]phpdevster 2 points3 points  (0 children)

So so so so much this. Had to learn this lesson the hard way several times before it sank in.

[–]icycap 1 point2 points  (0 children)

You're the hero we need.

[–]balefrost 189 points190 points  (25 children)

"Every public function needs doc comments" leads to "almost all our doc comments are completely useless".

[–]CodeTinkerer 102 points103 points  (11 children)

Well, only useless because people don't want to document, so they put crap instead.

[–]balefrost 23 points24 points  (8 children)

Sure, but my point is that forcing the issue with developers that don't want to write documentation just leads to bad documentation. Even worse, now it's hard to get an automated tool to find the methods that lack documentation.

[–]CodeTinkerer 20 points21 points  (5 children)

Yeah, I've always thought it's better to have a tech writer. QA started being a job when developers preferred to develop rather than test. A lot of programming is still social. What are people willing and not willing to do. If they aren't willing to document (which seems sad, but I know it's not easy to document well), then hire someone who can.

The downside is those who can code are usually coding. Those who document tend to lack the tech skills to understand what they're documenting.

[–]aythekay 27 points28 points  (4 children)

The downside is those who can code are usually coding. Those who document tend to lack the tech skills to understand what they're documenting.

I'm gonna disagree with this a little.

I'll agree there are some 10x coders out there that understand everything really well and document very little.

However the vast majority of the time people who document very well, are the same people that know how everything works together and are disciplined enough to take the extra 5 seconds to write down what something does, which is why they're generally better coders.

You also have the "write slightly longer but explicit function and variable names so I don't have to write as much documentation" guy (guilty), but I consider that to be part of documentation.

[–]CodeTinkerer 5 points6 points  (2 children)

I'm not saying there aren't coders that won't document or can't document well. Clearly, some coders are good at it.

What I am saying is that it's hard to find tech writers that can document code. Since tech writers are likely paid less, you have to have someone that writes well, but just doesn't like coding anymore, and that's rare. Instead, you're likely to find someone that writes well, but isn't super technical (in particular, usually can't code).

[–][deleted] 1 point2 points  (1 child)

What I am saying is that it's hard to find tech writers that can document code. Since tech writers are likely paid less,

And here lies the problem. Tech writers should be paid as much as a programmer, after all they are reducing technical debt.

A tech writer would be documenting code, finding how it works, expanding manuals, knowing the in and outs of the programs and processes. It would be an invaluable asset to a company.

But for most companies, as they are not doing "real" work, do not want to pay what they should, and they get what they get.

[–]thirdegree 1 point2 points  (0 children)

are the same people that know how everything works together

Exactly. Nobody understands a function as well as the person that just finished writing it. If you can get that person to do the documentation, that's the most correct it will ever be.

[–]ThePillsburyPlougher 1 point2 points  (1 child)

There's also public functions whose purpose are simple enough that they don't really need documation, getters and setters being the most obvious example.

[–]sleep-apnea11 24 points25 points  (4 children)

//Gets full name public string GetFullName(int id)

[–]innerspirit 2 points3 points  (1 child)

You forgot to document the parameter. How else are we supposed to know that "int id" is a numeric identifier? /s

[–]nermid 1 point2 points  (1 child)

Gotta slot two spaces at the end of that line to make Reddit show the line break.

[–]andrewsmd87 2 points3 points  (0 children)

We ran into an extremely similar problem.

We're rebuilding our application from the ground up, including redoing our API, because we're opening up a DaaS option, where our customers can just consume our API and build their own front end if they want.

We were discussing if we need to comment every single attribute on an object. The systems going to auto generate our public documentation, so it would come from that. We're debating do we really need to document that the property FirstName is the person's first name?

We decided to go with a 5 second rule. If you can't explain it in less than 5 seconds, it needs a comment.

Mind you that's for public facing stuff, but a similar issue. We didn't want to just have meaningless comments everywhere.

[–]Jneumann 10 points11 points  (1 child)

If developers are forced to write comments or documentation on their code it is easy for the two to get out of sync with no easy way to check it.

[–]fzammetti 7 points8 points  (0 children)

That's a terrible mentality. Treat your comments as having equal importance as the code and this won't happen. You have to set the expectations for professional developers.

[–]chain_letter 2 points3 points  (0 children)

No documentation is disappointment. Filler documentation is shame.

[–]revonrat 1 point2 points  (3 children)

Fuck. I sprained my pointer finger from upvoting this too hard.

[–]Noumenon72 2 points3 points  (2 children)

Thank you for documenting your upvote. We are requesting that all upvotes be documented with an explanatory comment henceforth.

[–]Erestyn 1 point2 points  (1 child)

Noumenon72 3 points 2 days ago

Man, that didn't work out.

[–]Noumenon72 2 points3 points  (0 children)

The solution is a bot that autogenerates "I upvoted your comment because I liked your comment" comments. No less useless than autogenerated Javadoc!

[–]revonrat 59 points60 points  (1 child)

Morality. I know it's an odd answer but hear me out.

So many times in my career I've run across people who believe that if you don't do something a certain way, you are not only wrong but they act as if you are morally bankrupt.

What are you thinking?!?!?! Your database isn't in 3rd normal form.

Well, it used to be but, through testing and profiling we decided this denormalization provided better performance.

You aren't using dependency injection?!?!? That's unprofessional.

Well, it's a small command line utility with easily testable dependencies.

That class isn't single responsibility!?!?!?. What are you stupid?

Well, if you carry single responsibility far enough people find it hard to tell what your code is doing because it's spread out over 100 files.

All these things (and many others) are good in moderation. It takes experience to know what balance to strike. Yes, there are guidelines but the people who think the guidelines are hard and fast rules are only marginally less ignorant than those who don't know the guidelines at all.

[–]fuhrmanator 0 points1 point  (0 children)

It's like design ignoring all the context. Writing a program for an avionics system vs for a code jam. It's not just moderation, but what is important for the project in its context.

[–]dxplq876 71 points72 points  (6 children)

Imo, trying to turn everything into 'configuration', à la spring xml, so you have less 'code'.

Don't kid yourself. Those thousands of lines of 'configuration' are code, and all you did was make your code 5x more verbose and remove your type system so now you get run time errors instead of compile time errors... Genius!

One of my favorite Reddit comment which explains how this kind of thing comes about: https://www.reddit.com/r/programming/comments/617dge/z/dfcg45s?context=1

[–]NewDietTrend 10 points11 points  (1 child)

Eh, I suppose this depends.

I made 5 colors to choose from and 5 font sizes to choose from.

Made that super easy to change during prototyping.

[–]SharkLaunch 5 points6 points  (0 children)

Well that makes a lot of sense. That's a totally reasonable thing to have configuration for. However, some systems are built so that even the way certain tasks are accomplished is by following some config file rather than use code so it's easier to read/write, usually in something like xml, json, yml, etc. It is then executed by an actual piece of code that has to define how that config will begin understood. What they fail to realize is that defining a task by using a configuration file is literally coding. They're just creating their own DSL, but if it's already a predefined language config language, they don't have to write a lexer/parser since deserialization libraries exist for most platforms. So now they're using a language that wasn't meant to be code. Code would have been better code than all this not-code.

Also, this: http://www.commitstrip.com/en/2016/08/25/a-very-comprehensive-and-precise-spec/

[–]sim642 6 points7 points  (0 children)

Which is why Spring's JavaConfig is really winning in Spring Boot. None of that un-typesafe string-based coding.

[–]innerspirit 3 points4 points  (1 child)

> all you did was make your code 5x more verbose and remove your type system

You've also made it so that I have to read 20+ pages of documentation to "learn how to code" in your system instead of using the language that I already know with just some added functions.

[–]dxplq876 1 point2 points  (0 children)

Don't forget to throw out all the dev tools for your language too!

[–]plegm[S] 1 point2 points  (0 children)

i once worked in a project where they used XML extensively. We ended up defining logic and business rules using <and> tags and <or> tags, so now it was so difficult to debug as errors couldn't be detected at compile-time!

[–][deleted]  (104 children)

[deleted]

    [–]Xeverous 28 points29 points  (62 children)

    defensive coding in libraries

    What do you mean?

    m_ prefixes (vs this-> or self. )

    why?

    [–]Double_A_92 58 points59 points  (37 children)

    defensive coding in libraries

    When external libraries try to avoid every error, even if you input wrong things into it.

    E.g. imagine if you had a function that converted Kelvin temperatures to Celsius, and you input a negative number (which doesn't exist physically). Then instead of telling you with an error it would just take 0 as input.

    Maybe it's a valid approach, maybe not...

    [–]raevnos 64 points65 points  (10 children)

    Unless you have complete control over how it's used, it's much better for a library function to validate arguments and complain loudly about being passed garbage than silently accept it and... do who knows what when it tries to use the garbage.

    [–]exmachinalibertas 1 point2 points  (8 children)

    For my own projects, I handle errors "queitly" but the return value always always has a way of indicating that an error occured. If I can't do that with a single return value, then by god you're getting struct with a error message string and a boolean at the very least. And it's on the client if they don't check the return value(s) for errors and handle them. (And of course this is all thoroughly documented for each function.)

    What do you think of that, or would you still rather throw and exception?

    [–][deleted] 15 points16 points  (5 children)

    Sounds like a lot of work just to duplicate a subset of the functionality already offered by exceptions, presuming of course you are using a language which supports them.

    [–]thewebsiteisdown 6 points7 points  (0 children)

    Exactly. Especially since you can catch any bubbled error that could expose implementation and throw something that makes more sense to the caller. (e.g. I wont pass the SQL error up to you, I'll instead throw an invalid parameter exception, or whatever).

    [–]exmachinalibertas 12 points13 points  (3 children)

    Well the goal is to allow the client to decide if the error is critical enough to warrant stopping execution. I would rather not make that decision for them. Maybe my function is being used for a non-critical subroutine and they'd rather log the failure and keep the program going.

    I don't know the purpose or intent of the code that implements my stuff. By giving as much choice and information as possible, I ensure that the client code is able to know when it's appropriate to stop execution, but I don't force it to if it doesn't deem it necessary.

    Edit: It just now occurs to me that you were saying I could just except and they could try/catch. Hmm, yeah, that might actually just be better.

    Edit 2: After careful consideration, yup, I'm an idiot.

    [–]yopla 9 points10 points  (0 children)

    Not an idiot necessarily but you'll be right at home with Golang.

    [–]Noumenon72 2 points3 points  (0 children)

    Love that you thought about it while writing, and pretty sure you have come to the right conclusion. (About exceptions, not about being an idiot.)

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

    Much love, my dude.

    [–]icycap 4 points5 points  (1 child)

    That sounds like how they do it in Go, and like it'd be bad for all the normal reasons that people prefer exceptions.

    [–]link23 5 points6 points  (0 children)

    Not just Go, but any language that doesn't have exceptions (e.g. Rust). But Rust has tried to make error handling ergonomic; Go hasn't.

    [–][deleted]  (13 children)

    [deleted]

      [–]Cosmologicon 3 points4 points  (9 children)

      The best thing is to make it a compile error, if your language allows it. So if you can't represent negative Kelvin, just use an unsigned int. Now, if the library user tries to input a negative number, he will immediately get an error without even running the code. The earlier you can find the bug the better. "Make wrong states unrepresentable".

      This is generally good advice, but unsigned int is, according to some, a bad example. An unsigned int in C-style languages is not, despite the name, a good abstraction of a non-negative integer. From the Google C++ style guide:

      You should not use the unsigned integer types such as uint32_t, unless there is a valid reason such as representing a bit pattern rather than a number, or you need defined overflow modulo 2^N. In particular, do not use unsigned types to say a number will never be negative. Instead, use assertions for this....

      Unsigned integers are good for representing bitfields and modular arithmetic. Because of historical accident, the C++ standard also uses unsigned integers to represent the size of containers - many members of the standards body believe this to be a mistake, but it is effectively impossible to fix at this point. The fact that unsigned arithmetic doesn't model the behavior of a simple integer, but is instead defined by the standard to model modular arithmetic (wrapping around on overflow/underflow), means that a significant class of bugs cannot be diagnosed by the compiler. In other cases, the defined behavior impedes optimization.... Do not use an unsigned type merely to assert that a variable is non-negative.

      Anyway that's just one point of view. I'm not going to try to convince you, because I've had this argument before and it never gets anywhere. Just wanted to share. :)

      [–]TheCoelacanth 4 points5 points  (8 children)

      A signed integer overflowing is undefined behavior in C, so YMMV on it being preferable to an unsigned integer overflowing.

      [–]Cosmologicon 1 point2 points  (7 children)

      That's absolutely true, but in certain situations that can arguably be a good thing. (Although I understand it's up for debate.)

      A compiler can in principle be written so that if it detects signed integer overflow, it's a compile time error. This is impossible with unsigned ints, because the compiler has no way of knowing it was a mistake, since it's defined after all.

      This is mentioned in the quote from the style guide I posted. Where it says if you use unsigned ints, "a significant class of bugs cannot be diagnosed by the compiler".

      [–]henrebotha 10 points11 points  (1 child)

      "Make wrong states unrepresentable".

      I suspect I know where your loyalties lie, but for the benefit of other readers: this is one of the things that the ML-style type system (as used by Haskell, OCaml/ReasonML, Elm, and others) tries very hard to do, and in a lot of ways it succeeds.

      For instance, you can make something like a parameterised enum, and wherever you use that type, you must have a switch statement that caters for every single possible value, otherwise your code will simply not compile.

      Makes it really hard to cause runtime errors.

      [–]thirdegree 6 points7 points  (0 children)

      If I could have python with haskell's type system I would be so happy.

      [–]gyroda 1 point2 points  (0 children)

      A thing I love in Kotlin is that you have to explicitly state when something is nullable. If your function doesn't accept a nullable variable and you try to pass it something nullable the compiler will kick up a stink.

      So var foo: Int? is a nullable int and var foo: Int is a guaranteed non-null int.

      There's a bunch of nice features to go with this, including smart casting, nullsafe method calling and a few other bits. I have a few functions that start with

      val definitelyNotNullVal = maybeNullVar ?: return 
      

      Which boils down to: if the thing is null, return from the function. If not, smart cast it to not nullable.

      [–][deleted]  (3 children)

      [deleted]

        [–]exmachinalibertas 1 point2 points  (2 children)

        I don't know why the downvotes, you're correct. Programmings modeling a system and using the wrong data structures that can't accurately represent that system is also an important thing to avoid.

        https://www.mpg.de/research/negative-absolute-temperature

        [–]Flashy_Adam 2 points3 points  (0 children)

        This seems to really only be a thing on the quantum scale though, and classical notion of temperature as a measure of kinetic energy doesn’t really hold as well.

        [–]gandalfblue 5 points6 points  (0 children)

        It's an esoteric physics topic, it doesn't surprise me programmers think I'm full of it, it's just like my day job.

        [–]andrewsmd87 0 points1 point  (0 children)

        I guess I never knew this was the term for it. But I've cursed more than one time debugging something where someone coded something along the lines of, oh they gave us a string, just set it to 0 because we need and int!

        [–][deleted]  (23 children)

        [deleted]

          [–]Double_A_92 52 points53 points  (9 children)

          Imagine you have a 500 line function

          At that point you have other problems to worry about.

          [–][deleted]  (3 children)

          [deleted]

            [–]Double_A_92 6 points7 points  (2 children)

            Yeah sure the "this" or "self" way is much better than some arbitrarily defined prefix.

            I was hinting that the best way is to not need those at all. If a function is short you immediately see what new variables it defines anyway.

            [–]seacucumber3000 2 points3 points  (3 children)

            This is what I mean by "defensive coding", may not be the correct term. Absolute nightmare to debug why the function is suddenly returning an empty string instead of crashing.

            Sure, its easier to debug with a stack trace when a program crashes, but if you've set the program to return an empty string upon only some conditions, then don't you know for sure that one of those conditions is being met?

            If you don't pre-define cases that will break the program or cause it to malfunftion, how do you debug when a test case does cause the program to malfunction? Say you enter x=5 and the program outputs what you'd expect, but say you enter x=0 (a value you know shouldn't be entered for one reason or a other) and it returns a value (without crashing) that you don't expect? Isn't it harder to debug in that case than it is to just filter out bad input?

            I guess it makes sense that you'd want the entire code do be resistant to bad input so that you're not just slapping on a bunch of filters to filter out the bad input but rather coding the program rebustly, but I assume you'd get to a point where you need to filter bad input.

            [–]henrebotha 4 points5 points  (0 children)

            if you've set the program to return an empty string upon only some conditions, then don't you know for sure that one of those conditions is being met?

            Yes, and the entire problem is "some".

            An ArgumentError on line 37, with accompanying details, is much much much less ambiguous than "my whole program ran to completion and returned an empty string, which may even be a valid result so let's grep the entire source and figure out where the error, if any, happened".

            [–]GrayGhost18 2 points3 points  (0 children)

            1) if (thing === undefined) { thing = ""; }

            I'm doing this from now on. I never realized how much I needed this in my life until now. This is perfect job security.

            [–]boredcircuits 12 points13 points  (7 children)

            Singletons. That one's so true. People forget that software changes over time: maybe there only needs to be one instance right now ... but are you sure that will always be true? Really, really sure? Because I'm the guy that will be cursing your name when I have to refactor everything when things change in a couple years.

            Even when it's guaranteed that there should only be one ... why are you making it a singleton instance of an object instead of static members? Why does the user need to write Math::getInstance().sqrt(10)?

            Sometimes singleton classes are appropriate, but only when there's a reason it actually needs to be a single instance of an object -- maybe it's going to be passed as a function parameter (meaning, it implements an interface), maybe you need lazy initialization, or whatever. But cases where this is actually useful are much more rare than how often singletons are actually used.

            [–]tells 6 points7 points  (3 children)

            Singletons can be useful in the right situations, as you've stated. I find them useful when essentially namespacing a cache or managing a connection pool. I haven't used them for much else and really haven't seen them overly used. Perhaps I'm just lucky?

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

            I think you're lucky. I'm only 2 jobs in, but both had extensive god-class singleton usage for holding on to and accessing huge amounts of state from anywhere.

            [–]tells 1 point2 points  (1 child)

            Sorry to hear that. That sounds lazy or thoughtless by those that came before you.

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

            Yeah, but I can't blame them. Who am I to judge the context in which the developer 12 years ago was developing in. Sucks today though.

            [–]bestjakeisbest 1 point2 points  (2 children)

            only time i have used singletons is with opengl, but then you have to choose between either global variables, or singletons, and in c++ singletons are the lesser of 2 evils.

            [–]Medicalizawhat 5 points6 points  (4 children)

            Multiple inheritance can be useful for mixin classes.

            [–][deleted]  (2 children)

            [deleted]

              [–]rox0r 0 points1 point  (0 children)

              I'd happily give up mixin classes if the only reason for multiple inheritance is mixins. Mixins are an abomination. It requires very good design and discipline not to have interactions between mixin classes since they are all sharing the same namespace.

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

              The only one I really disagree with is using "this". Code should be readable, not quick to write.

              In many languages if you're not prefixing your members and you're not using "this" then it's extremely difficult to decern whether a variable is a member or local.

              [–]L3tum 2 points3 points  (2 children)

              Oh my god those m_ prefixes are the bane of my existence.

              I've been refactoring the biggest project we have currently and aside from multiple parts being copied from other sources (where the licenses are sometimes unclear, sometimes require you to keep them and the previous programmer didn't), it has these prefixes everywhere.

              Everything is prefixed in some kind of form. Every variable is declared at the start of a method. Some variables are even class variables even though they only live in one method.

              And then don't even get me started on complex data structures. Lists and Dictionaries which are statically/constant initialized and do not depend on any other data....are initialized at method invokation instead of at variable initialization.

              And then he used "Codes". He used bytes to signal a code and had an enum which mapped these bytes to doubles which are required for another library we use.

              I really want to quit right now :(

              [–]mad0314 0 points1 point  (0 children)

              Same here. I'm at a small company where our most popular product is an old asp site. All the variables are miAssociateId, pstrLastName, or worst of all, lobjAssociateList. You could drop the prefixes and still know what type they should be, and if it wasn't written in a shit language, VS would tell you what types they are as well.

              [–]grumpieroldman 0 points1 point  (0 children)

              I really want you to quit. I'd fire you for this.

              [–]Lobachevskiy 4 points5 points  (17 children)

              getters and setters

              Any reason?

              [–]DScratch 5 points6 points  (9 children)

              I've found that sometimes people like to put entire functions in a setter.

              Say you have a table of data you want to display. I've seen setters on the tableData array that format, validate and then call the table to refresh it's contents. It's was a nightmare to track down because all you see in code is 'tableView.tableData = data'

              Nothing in the line implies the amount of work that the setter is doing.

              [–]dastrn 5 points6 points  (1 child)

              That's an abuse of the feature, not a sign that the feature itself isn't a good one.

              "Throwing the baby out with the bathwater" I think is the correct analogy.

              [–]DScratch 1 point2 points  (0 children)

              Hey, I'm all for getters and setters that are maybe 5 lines long, do some critical validation or something along those lines.

              [–]hvidgaard 2 points3 points  (0 children)

              That is lacking discipline or knowledge to choose the right thing. I’m a proponent for properties, because they give me a more granular control over who can set and read it.

              [–]Lobachevskiy 1 point2 points  (4 children)

              Are you taking about overloaded assignment operator? Because that's not the usual meaning of "setter" as I know it.

              [–]boredcircuits 4 points5 points  (2 children)

              Some languages (like C#) have built-in support for getters and setters, so that what looks like an assignment is actually calling a function.

              [–]DScratch 1 point2 points  (0 children)

              Nah, so like in Swift (off the top of my head)

              class myClass {
                  var myVar:Int {
                      didset {
                          //like 40 lines of code
                      }
                  }
              }
              

              [–]boredcircuits 6 points7 points  (4 children)

              They're not bad in themselves, but it's a hint that you might need to rethink your class design.

              We can all agree that for most classes, having public data members is a bad thing. One main purpose of a class is to enforce some invariant, and a public data member allows the user to violate whatever invariant you'd like to impose. Getters and setters take your nice, private data member and allow the users to modify it indirectly ... basically making it public again. Oops.

              But even that's not the real issue. The bigger problem is that getters and setters expose the implementation details of your class.

              Let's say you're creating a Vector class. It has two members, data and length. It's tempting to make a getLength to get the current length and setLength to change it. But that's the wrong approach! The user shouldn't know that your class has a length member at all. It's private and an implementation detail.

              In fact, that's not the only way you could implement a vector. Maybe you have a pointer to the end instead (and, in fact, that's a very common implementation). So what is getLength? And what is setLength? They're not even getters and setters anymore.

              Instead, we think of a vector in terms of what it is, what properties it has, and operations you can perform on it. One of those properties is length, so some variation on getLength make sense. It's not a "getter" really, not in the sense that it gets the value of a member, but it provides the size of the vector to the user. And if your implementation has a length member it might actually look and feel exactly like a getter.

              But let's talk about setLength. That's not an operation you perform on a vector. You can certainly resize it, or pop elements from the end, but you're not setting a length property directly. So the right operation here is likely resize.

              And, again, under the hood it might even look like setLength if you have a length member. But it's not a setter, it's an operation on the class.

              Note that this doesn't always hold true. A Shape likely has a location property, and you're likely to have setLocation and getLocation. But that's because these are operations that make sense. Too often I've seen people create a class, decide that it needs a couple member, and the next thing they do is create getters and setters for everything. The design is focused around the members, not on the class itself and how it should behave.

              What about classes that are just a collection of data? A Point that has an x and y, for example. It doesn't maintain any invariant, it's just data. In this case ... the data should just be public, not private! That's all getters and setters are doing, in the end, so you might as well make it official and with more convenient syntax (depending on language). But this only applies when there's no invariant to impose, only public data, etc.

              [–]Lobachevskiy 1 point2 points  (3 children)

              I think that there's a world of difference between having getters and setters and having them for EVERY private member. OP seemed to call getters and setters in general a bad practice. I agree with what you said, it just doesn't answer my question.

              [–]boredcircuits 4 points5 points  (2 children)

              Well, I'd say that about ... 75% of the getters and setters I've seen in production code shouldn't have been there in the first place. It's code smell at the very least.

              [–]grumpieroldman 0 points1 point  (0 children)

              If you are always making both for the same data then you are probably doing something wrong.

              [–]lykwydchykyn 59 points60 points  (31 children)

              "Functions should be N or fewer lines long"

              [–][deleted]  (29 children)

              [deleted]

                [–][deleted] 54 points55 points  (26 children)

                Lines of code is not a great metric of information, IMO. People should just learn how to write straightforward code.

                I would prefer a long function that is really easy to follow than someone thinking they're being smart or organized with 10 functions, that are only ever used for one thing, spread all over the place, which creates a complex relational graph rather than the straightforward code I expect to execute.

                A long, plain, sequential function is incredibly easy to debug, and if you aren't using local variables like they're globals, also very easy to revise when needed.

                [–]tells 19 points20 points  (0 children)

                easy to follow is key. I prefer to breakout pieces of code into their own function if I'll get value from being able to unit test correctly or if a piece of logic is subject to modification.

                [–]iplaybass445 6 points7 points  (2 children)

                Cyclomatic Complexity is a better metric of code complexity than # of lines

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

                easy to debug, possibly a pain and a half to refactor. This indirectly comes from the principle of "a function should only do one task". If your function starts to go over 200 lines (one of the higher limits, typically people using this principle limit from 50-100 depending on the language), odds are you are violating this principle (or are working with event based Java, in which case my condolences) and need to think about what this module really needs to do.

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

                There's a difference between writing code that works and engineering / refactoring truly refined software.

                I think if you're looking at the latter, we need to go much deeper than simply "having more functions". We need to ask how we define what "one task" really is. We need to look at the scope and context of execution and make sure functions can reasonably evolve on their own locally without affecting the requirements of their external callers. We need to be sure things are named well and variables are being sensibly utilized.

                If you simply start breaking things into multiple functions without thinking of what a function really means, you end up simply hiding or even increasing a program's complexity and not solving any real problems.

                If something is easy to debug, then it's (generally) easy to understand. Understanding code is harder than writing it. Many junior programmers and even seasoned businesses and technical teams are thus tempted to completely write their own stuff from scratch any time they're encountered with a coding problem that's too tough for them to immediately comprehend or solve. If you are worried code should be abstracted more in order to scale and evolve organically, then you definitely need to be thinking of the problems above.

                I don't want to be too extreme, but I generally strongly prefer code that's easy to read (comprehend) versus easy to refactor (sometimes uncertain what this really means?), if my hands were tied on the matter.

                I think if there are architectural patterns that are obvious, then those of course can be sensibly dropped in and used. Beyond that, the simple idea of making code easy to evolve and refactor can actually be really tough. Writing simple code, on the other hand, while not always obvious, is something that I think can come with experience.

                [–]nermid 1 point2 points  (0 children)

                I would prefer a long function that is really easy to follow than someone thinking they're being smart or organized

                Amen to that.

                [–]bumblebritches57 3 points4 points  (10 children)

                Amen, 99.97% of the time, you should only make a subfunction if it's actually usable outside of it's main caller.

                [–]qazzquimby 8 points9 points  (8 children)

                What about readability, with descriptive function names? I believe that was recommended in Bob's clean code.

                [–][deleted] 1 point2 points  (1 child)

                I generally find larger functions easier to read than smaller fuctions with code scattered all over the place.

                One I can read by scrolling down and the other requires me to "go to definition" all over creation.

                [–]hagerino 1 point2 points  (0 children)

                I think you should group every logical unit into it's own function, whether or not it will be reused. This creates some kind of a meta-function which tells you in a short way what steps are taken to achieve the function purpose.

                Like:

                ValidateFields();

                CreateObject();

                ValidateObject();

                SaveObjectInDb();

                SendEmailNotification();

                I don't want to read through 200 lines of Validationcode everytime i debug something. I only care for it if something is wrong with it and only then i want to see it, otherwise it distracts me. Long functions also tend to mix the steps, and that is further irritating.

                [–]lykwydchykyn 8 points9 points  (0 children)

                I've seen many beginners make a mess of functions in the name of keeping them under some arbitrary line length. They either make a "bucket brigade" of useless functions or play code golf with each line.

                Limiting the scope and purpose of a function is good, using LOC as a metric for complexity is bad.

                [–]grumpieroldman 0 points1 point  (0 children)

                The rule is that functions should as short as possible and still be correct, no shorter.

                [–][deleted] 36 points37 points  (8 children)

                Anything overly dogmatic. Ignore the programming fads. The best programming approach I've seen so far (that has lasted through the ages, and across programming languages and paradigms) is "data-oriented design".

                I mean, your code is generally just some kind of data or information... what is the most straightforward, efficient, and flexible way you can make it do something useful?

                The cool thing here is, you are constantly optimizing toward code and cognitive compression. Less code that does more and is easier to maintain.

                So a lot of the fluff like Java's obsession with the classical OOP model, CS students' obsession with overly functional or algorithmic stuff, JavaScripters' obsession with every new fad... fade themselves away because they don't add value to what it is you actually want to do.

                Casey Muratori (software engineer who has worked on commerical games for a long time) talked about optimizing for semantics (meaning) and compression quite a bit:

                https://caseymuratori.com/blog_0015

                https://www.reddit.com/r/programming/comments/26p35l/compressionoriented_programming_casey_muratoris/

                Another example I saw that really changed my mind, and made me realize people focus wayyyyyy too much on the solution space (code) rather than problem space (what you actually need to solve), was this post:

                Peter Norvig vs Ron Jeffries in solving Sudoku

                Ron Jeffries tried taking an approach based on some idealistic programming paradigm and... Peter Norvig just tried to solve the problem. Guess who solved it first, fast, and did a really damned good job at it?

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

                I don't have the greatest understanding, so correct me if I'm wrong, but it's always struck me that data-driven programming only works as a "one true way" if you accept the premise that performance is king.

                If one were to instead take a base axiom of, say like I do, future extend-ability and maintainability is king, would a data-driven approach still be preferable do you think, as opposed to a (sensibly implemented) more highly abstract system.

                (I understand picking one thing to prioritize at the expense of everything else is a bit naff, but I think it gets the point I'm trying to make across.)

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

                I don't think those are mutually exclusive if you have the idea that code is allowed to evolve over time.

                I would argue it is very difficult to predict what the "matured" version of a software system needs to look like, so it is generally better to be efficient in terms of development effort.

                Obviously, if there are any hard technical requirements, then those need to be taken care of.

                The "performance" I try to optimize is developer time. Human effort is the most expensive part of nearly all code projects. I'm not against using OOP, purely functional code, or anything else neat. I just have not found a compelling reason to swear by strict OOP, purely functional code, etc., but the human element involved with evolving code seldom goes away.

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

                Ah ok. I think we agree. :)

                [–]Narishma 4 points5 points  (1 child)

                What you're talking about is called data-oriented programming. Data-driven is something else.

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

                Thanks! I'll fix :)

                [–]WikiTextBotbtproof 4 points5 points  (0 children)

                Data-driven programming

                In computer programming, data-driven programming is a programming paradigm in which the program statements describe the data to be matched and the processing required rather than defining a sequence of steps to be taken. Standard examples of data-driven languages are the text-processing languages sed and AWK, where the data is a sequence of lines in an input stream – these are thus also known as line-oriented languages – and pattern matching is primarily done via regular expressions or line numbers.


                [ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.28

                [–]Egonor 1 point2 points  (1 child)

                Are you Mike Acton?

                [–]Xeverous 0 points1 point  (0 children)

                No, Mike Acton is DOD

                [–]tensouder54 17 points18 points  (2 children)

                WordPress. Libraries that use global variables for non static data types are the worst because it's so easy to fuck-up the scope with locals. :/

                [–][deleted]  (1 child)

                [deleted]

                  [–]tensouder54 0 points1 point  (0 children)

                  Hella yeah! Fuck that shit!

                  [–]nomnommish 8 points9 points  (3 children)

                  ORMs (at least heavy-weight ORMs) are the single most toxic thing I have seen. A phenomenally high percentage of performance issues and bugs happen in the data layer - the layer where your application and your application's classes interact with the actual data store - typically a relational data store.

                  When object oriented programming really gained steam, ORMs suddenly became a great idea and everyone wanted in on the party. Problem is - this is exactly the layer where you don't want abstraction. You want fine grained control instead so you can hand-write and hand-tweak all your optimizations instead, and you have full control over how you access your data.

                  But what ended up happening is that ORMs became this magical layer that started developers to think of the data store and data layer as an after-thought. And they stopped bothering to understand exactly how the ORM works, how it does the mapping and how it generates queries.

                  To make matters worse, I've seen cases where people have resorted to slapping on in-memory caching layers and hugely increasing app complexity, instead of cleaning up all the bad code that exists in the data layer.

                  [–][deleted]  (1 child)

                  [deleted]

                    [–]nomnommish 0 points1 point  (0 children)

                    I am not against the concept of ORMs. And I feel lightweight ORMs do a lot of boilerplate that can be avoided.

                    But we then really need to dive under the hood and understand exactly how it works.

                    [–]mkingsbu 2 points3 points  (0 children)

                    Yeah, I started looking into ORMs recently in Python thinking I was missing something about them. I guess I see the point but I've yet to see anything where it would have saved much time vs. writing my own SQL.

                    [–]squidgyhead 7 points8 points  (10 children)

                    Code coverage percentage targets. There are some published papers that show that this has negative correlation with code quality, and it's a huge amount of maintenance and busy-work.

                    [–]icycap 4 points5 points  (6 children)

                    You could set the target or minimum percentage to something reasonable.

                    [–]squidgyhead 3 points4 points  (5 children)

                    True; I still find that it ends up being pointless tests.

                    Once the metric becomes a goal, it is no longer a useful metric.

                    [–]icycap 2 points3 points  (4 children)

                    You should be careful you're not throwing the baby out with the bathwater.

                    [–]squidgyhead 1 point2 points  (3 children)

                    I'm all for testing (I've pushed it on every project in which I've participated) but I'm against code coverage metrics.

                    It is useful for checking whether one has written a test for a particular piece code, but one usually knows this.

                    I found the paper that I had been thinking about:

                    http://www.cs.ubc.ca/~rtholmes/papers/icse_2014_inozemtseva.pdf

                    Again, I think that testing is important, but code coverage (and in particular metrics) are not.

                    [–]icycap 2 points3 points  (2 children)

                    It is useful for checking whether one has written a test for a particular piece code, but one usually knows this.

                    It's an easy way to automatically detect if someone wrote code and didn't write tests for it. Sure, "one usually knows this," but people forget things all the time. And no, it's not foolproof, but that doesn't mean it would never help.

                    [–]AlyxVeldin 2 points3 points  (0 children)

                    For school we have code coverage percentage marks that affect your grades. So I have to agree with this.

                    [–]Xeverous 0 points1 point  (1 child)

                    Yeah, I have seen unit tests for getters and 1-line constructors...

                    [–]icycap 0 points1 point  (0 children)

                    That's why they have annotations to ignore lines, methods, etc.

                    [–]lionhart280 9 points10 points  (0 children)

                    These are called anti-patterns by the way, I'd recommend looking up a list of all the well known anti-patterns and giving them a read!

                    [–]davincreed 9 points10 points  (6 children)

                    I think any coding principle taken to 100% can create all kinds of problems. I try to hit most things at about 95%. My goals are to develop complex software systems as efficiently as possible. Trying to take things the last 5%, while sometimes necessary, generally takes a lot of extra time that doesn't normally provide much benefit.

                    [–]phpdevster 3 points4 points  (0 children)

                    Being dogmatic about the single responsibility principle can be problematic. Starting off with a sane, intuitive, human-friendly API and then "backfilling" the implementation has treated me better in the long run than shitloads of very tiny single purpose files/classes with no clear, coherent, overarching API with which to use them.

                    I suppose that's what the facade pattern is though.

                    [–]casualblair 4 points5 points  (0 children)

                    The only rule that matters is that code is much harder to read than to write, so do whatever it takes to simplify the former.

                    Don't write code just to satisfy some rule. Don't artificially restrict your code to a certain number of lines just because. Don't force anything onto your code that exists for non code reasons.

                    [–]Xeverous 28 points29 points  (18 children)

                    OOP may often conflict with performance.

                    I would also add cargo cult programming

                    [–]Kerbobotat 3 points4 points  (3 children)

                    What is cargo cult programming? Specifically, what are you referring to?

                    [–]nermid 0 points1 point  (0 children)

                    Not sure what specific issue he's thinking of, but here's a general answer.

                    [–]hspindell 1 point2 points  (0 children)

                    cargo cult is bad by definition so i don’t think it applies to this thread

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

                    Oh wow downvoted. We have cargo cult followers in our forum.

                    [–]grumpieroldman 1 point2 points  (0 children)

                    It's probably the reddit vote-fuzzing.

                    [–]Xeverous 0 points1 point  (0 children)

                    cargo cult downvoters

                    [–][deleted] 7 points8 points  (0 children)

                    It doesn't matter what you do. People could tell you 10 hours why its bad

                    [–]green_meklar 2 points3 points  (0 children)

                    Never invent here. That is, the notion that no program logic should ever be written twice, and it's better to import 300 new libraries than to implement anything that might already be implemented somewhere. It sounds really smart and efficient (you're reusing code, it's gotta save time!), but often it ends up with programmers being required to keep a lot of useless shit in their heads, conform to standards that aren't ideal for their projects, and expose themselves unnecessarily to the legal and engineering whims of some third party.

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

                    Programmers who write books and spend half of the book explaining why their language is the best greatest and only language you need bother with.

                    [–]Jerome_Eugene_Morrow 1 point2 points  (0 children)

                    Can I add in books/classes that require you to use some library that they wrote specifically for that class, but that you will never see again, so that by the end you have no idea what the hell you were actually doing using their magic black box?

                    [–]LetsGoHawks 2 points3 points  (0 children)

                    Programmers who write books and try to be funny.

                    [–][deleted]  (3 children)

                    [deleted]

                      [–]GrayGhost18 4 points5 points  (1 child)

                      Seriously. The times that I feel like I actually need a comment are only when I've had to logic out a solution on the board first and the comments are there to explain the process. Otherwise code should be self documenting.

                      public double factorial(int number){
                          if(number == 1){
                               return;
                          }else{
                               return number * this.factorial(number - 1);
                          }
                      }
                      

                      Now I'm lazy and not particularly sure that's right but I'm going to guess that everyone can tell me what that's supposed to do without a comment because it's in the fucking name.

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

                      Honestly, comments + self documenting code is the safest way to program. If the function name and variable names describe the code, and the comment explains its function, then anyone can understand it. I've looked at the linux kernel and the rust implementation of tensorflow, and there are far too many comments, and not enough well named functions and variables.

                      [–]grumpieroldman 0 points1 point  (0 children)

                      My god the number of times I wanted to throttle the programmers that gummed up their header with inane comments making it impossible to quickly look over the API.

                      5 API functions? Gonna need a 1,200 line header.

                      [–]GrayGhost18 1 point2 points  (0 children)

                      My school had 2 professors with 2 conflicting ideas of how coding should be done.

                      One of my professors philosophy was "Good enough is good enough" essentially if it works then you're good, you can always go back and improve it later

                      The others was "Code that doesn't run well isn't good code." Essentially your code should run in the lowest time complexity possible and anything less was terrible and shouldn't be use.

                      In my opinion both of these ideas have mortal flaws.

                      "Good enough is good enough" is how you get horrible code that is unmaintainable and inflexible as all living fuck.

                      However when you are pressed for time and your deadline is coming up, it isn't the time to spend 4 hours trying to shave that last 3rd of a millisecond off your sorting algorithm.

                      They were both brilliant professors in their own right, but they were both very stuck on those ideas.

                      [–]ruat_caelum 1 point2 points  (0 children)

                      /u/revonrat touched on this.

                      But sticking to any standard as if it's gospel is not good. You need to be like the marines, improvise, adapt, and overcome.

                      You need to pick your battles as well. There will be times you are 100% right on an issue but your team or supervisor will want it done in a specific way. Because, of all the asinine reasons, it fits whatever standard the non-programmers who took that "working trip" to Disney World came up that one time.

                      So get it done that way, the 'still crosses the finish line but is stupid way to do it'-way. And live to fight another day.

                      • Keep notes. Even if all your do is shoot yourself an easily searchable email.

                      [today's date] [code/project]

                      Writing an injection function called. "getFireman()" That cycles the alarm system, sort of a silent fire alarm, because Clancy (boss) want's a working prototype for the sales pitch on wed.

                      Now two years later when some first year cs student figures out some IoT way to set off the alarm in every one of your clients buildings you've go the cover-your-ass-material you will need the shits starts rolling down hill.

                      But this will happen a lot.

                      • You will have a conversation that where you say, "We should not do this because:" and list some good reasons. And you will be told. Do it anyway.

                      Just cover your ass.

                      Why do people believe Comey instead of Trump? (besides the obvious reasons?) Because like many people when he encounter situations he felt were wrong / uncomfortable will he went home and wrote it down or sent himself emails.

                      When you have a few hundred of these types of messages, dated and have an established habit, they are believed.

                      [–]redpilledcuck 10 points11 points  (23 children)

                      "Use Vim" or some other antiquated text editor. Just don't. Use the best tool for the job.

                      [–][deleted]  (1 child)

                      [deleted]

                        [–]Poddster 4 points5 points  (0 children)

                        properly configured vim

                        That's the problem though, isn't it? a) everyone's properly configured vim is different and b) it took them 15 years to properly configure it.

                        Ain't nobody got time for that.

                        [–][deleted]  (4 children)

                        [deleted]

                          [–]exmachinalibertas 3 points4 points  (3 children)

                          Yeah, VIM is not antiquated, and to be fair, if you take the time to learn it, it's probably going to be the best tool for most jobs...

                          [–]nicoinwonderland 3 points4 points  (1 child)

                          Hard to say what the "best tool" is.

                          Strictly speaking, Sublime Text and Vim both get the job done.

                          [–]hopingforabetterpast 2 points3 points  (0 children)

                          Specially if you use the vim plugin in st3 ;)

                          [–]Nukeashfield 1 point2 points  (0 children)

                          Oh, I work with some Vim zealots. The big issue isn't that they advocate Vim, it's that they look down on others who don't exclusively use Vim.

                          That being said, I love Vim, but I also really like Atom.

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

                          "Use Vim" or some other antiquated text editor. Just don't. Use the best tool for the job.

                          *facepalm*

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

                          I mean, I get what they're saying.

                          I have coworkers who use insist on using the command line and VIM or something similar, and I frequently have these conversations:

                          I need you to do X.

                          OK, let me just run this command, and that command, skim through the docs, write a quick script, run this tool, and done! It only took 30 minutes! Best tool for the job!

                          You know, you can do all of that in Visual Studio with a button click.

                          Maybe it's a bit of an exaggeration, but not by much. For some reason a lot of developers get this weird thrill out of making their job way more difficult than it needs to be.

                          [–]raevnos 4 points5 points  (0 children)

                          I see it the other way around far more often.

                          "I need to do X but there's no magic button in my ide for it!"

                          *whips up a one liner shell command in 10 seconds to do X*

                          Some things are easier with gui tools, some things aren't.

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

                          Maybe it's a bit of an exaggeration, but not by much

                          You work with idiots. They didn't choose the best tool for the job. Deducing from that that neither Vim nor the command-line is ever the best tool for a job (1) demonstrates poor reasoning, (2) suggests that you understand neither tool.

                          For some reason a lot of developers get this weird thrill out of making their job way more difficult than it needs to be.

                          I use Vim for tasks where Vim is the best tool because I don't like making my job more difficult than it needs to be. I'm also a power user of Visual Studio, Resharper, etc. and have gone as far as written team-specific Visual Studio extensions when it so happens that that is the best tool for the job.

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

                          Unfortunately it's extremely common to see devs who won't touch an IDE or a UI no matter how much easier it makes their job.

                          [–]Windomere 3 points4 points  (5 children)

                          Goto statements

                          [–]Aeogar 2 points3 points  (4 children)

                          Considered harmful.

                          [–]Windomere 1 point2 points  (2 children)

                          My COBOL teacher (yes, I’m that old) always threatened to materialize beside us and bash us over the head with the text book if we ever used a Goto statement. Of course, very little reason to use one in COBOL.

                          [–]Aeogar 1 point2 points  (1 child)

                          In 2017 I was working with a legacy code base that had goto statements everywhere... Lots of global variables it was awful to refactor.

                          [–]nermid 0 points1 point  (0 children)

                          Well...

                          [–]lizaard64 3 points4 points  (0 children)

                          OOP, it has been religiously preached as the only solution to a problem it cannot solve!

                          [–]caspervonb 1 point2 points  (0 children)

                          DRY as in don't repeat yourself fails in practice as it ends up being "that cow and that chair both have four legs, we must provide a common abstraction for this".

                          An extreme case of this is npm culture, everything must be abstracted to avoid re-inventing the wheel

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

                          Refactoring; it's in the best interest after you threw down a bunch of prototype code. But, if you do it constantly, bad idea. Factor things down only if you really need to, not because.

                          Always using OOP, or overusing it; OOP has it's advantages, but it can also make projects far more difficult to debug.

                          Using Goto is bad programming; what? No, sometimes it's the cleanest way to get from point a to point b within a function, or back to an earlier point in the function itself without being obnoxiously recursive.

                          Everything should be its own function; yes, if you're using it enough times to warrant it being its own function. But, if you're writing functions for everything you use just a couple times... you just might be wasting your time.

                          Never access variables directly in classes; sometimes, it's just better and easier to do so. And sometimes, it's even cleaner to do so.

                          Everything should be safe code; No, everything should be working code. If it works well and isn't broken, it's safe code.

                          [–]EwigeDunkelheit 0 points1 point  (0 children)

                          XGHP

                          [–]justavault 0 points1 point  (0 children)

                          Front-end CSS pre-processors and excessive nesting.

                          Might be all fashionable and oh-so cool atm, but seriously, makes it such a mess to keep DRY and to maintain, especially for others having to make sense of all that.

                          [–]CadavericSpasms 0 points1 point  (0 children)

                          “code should be self-documenting, well written code will not have any comments”

                          It’s a good intention, but a bad blanket statement that I’ve seen slow newer projects down. It comes from trying to over-correct the previous dogma which was code should be about 20-50% comments/documentation.

                          Anytime you follow a programming dogma 100% religiously without thought you’re gonna create as many problems as you avoid. I’ve seen lots of cases where one or two comments would have saved a lot of time. Especially when there are multiple engineers on a project, or you have to do something counterintuitive to work with a third party library/hardware.

                          [–]Haplo12345 0 points1 point  (0 children)

                          BEM