Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have been reflecting lately on the dogma that circulates in the world of software development. Ranging from "goto is evil" to "singleton is an anti-pattern" or "reflection is slow".

No concept is harmful in itself. Asserting one of the aforementioned is harmful is similar to saying that "a hammer is dangerous" -- Well, of course it is, if you use it incorrectly.

So I pose a question to the open minded amongst us, how do we deal with it when people regurgitate this dogma? What if it's a really good place to use a singleton, goto, or reflection, and then some non-thinker comes along and flames me for it?

share|improve this question
9  
How about "Free Your Mind"? Seriously, though, I haven't used GOTO in years. If you use it a lot, consider the possibility that your code could be better quality than it currently is. – Robert Harvey Nov 4 '11 at 18:06
8  
The dogma here is that they should rules should be blanket (blindly) applied. The rules are a good starting point but there are always situations were they do not hold. So for beginners they are good rules, for experts they are good guidelines. Unfortunately everybody that tries to break the rules think they are experts in reality they are not. – Loki Astari Nov 4 '11 at 18:08
4  
Well, you sure can find good places for goto, reflexion and singleton. I know for sure also that thoses are used in 99% of cases where they shouldn't. Thus, considering thoses stuff armfull in the first place is a safe assumption, as long you know why, and allow you to break that rule when the why clause isn't true anymore. Anyway, as thoses are mostly badly used, this is up to you to justify the use of thoses, not others to justify why you shouldn't. – deadalnix Nov 4 '11 at 18:09
16  
One of my rules: "Never break a rule you don't understand." (Yes, I do understand this rule.) If you don't know when to use goto and when not to, you'll probably come up with better software with a blanket prohibition than without one. Just like I encourage C++ programmers without a lot of experience to always us std::shared_ptr<> - it's not really a good general rule when you know why you're using it and when not to, but it'll probably help a beginner a lot. – David Thornley Nov 4 '11 at 18:20
7  
It is a poor attitude to frame reasoned principles and general (not absolute) rules as "dogma". – Eoin Carroll Nov 4 '11 at 20:28
show 18 more comments

closed as not constructive by Robert Harvey, Mark Trapp Nov 5 '11 at 6:07

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or specific expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, see the FAQ for guidance.

10 Answers

up vote 15 down vote accepted

I love Reflection too. That doesn't mean it's not slow. (Not to mention a very good way to violate encapsulation.) But it's very useful for solving certain classes of problems that are difficult or impossible to solve with other techniques, particularly the problem of library writers using too much encapsulation and locking users out of internal values they need to be able to get at for whatever reason. I've written a handful of blog posts about doing exactly that in Delphi.

But it's important to keep in mind that things that are considered harmful are considered harmful for a reason. You said "of course it is if you use it incorrectly," but some things get used incorrectly far more frequently than others. So I try to use such techniques carefully. There's a place for them, but as a general rule they should only be used when there's no way to do what you're trying to do with safer techniques, or at least not without horribly overcomplicating the code.

share|improve this answer
1  
Reflection might be slow, but using reflection to direct run time code generation takes care of that problem. :) – Steven Jeuris Nov 4 '11 at 19:00
1  
@Steven - but run-time code generation is slow (compared with not needing it - as usual, maybe an unfair comparison), especially if the compilation includes thorough optimisation - and if it doesn't, the generated code is slow. In theory, in at least some cases reflection-based tricks could be handled by static analysis at compile time, but I don't think I've seen this done in any serious way. The nearest I can think of ATM are some of the mixin-layer tricks that can be done with C++ templates. – Steve314 Nov 4 '11 at 22:48
@Steve314: Of course you shouldn't do run-time code generation if you are only going to run that generated code just once ... then you have the cost of reflection + compilation. Why would run-time generated code be slow? If the code you generate is fast, run time generated code should run just as fast as compile time generated code. – Steven Jeuris Nov 4 '11 at 22:51
@Steven - Only if the same compilation process is used. This seems rare for run-time vs. compile-time. To optimise the generated code better, you have to spend more time optimising - it's a trade-off. The greater the executions:generations ratio, the more value there is in more sophisticated optimisation - and that ratio is normally greatest when all compilation is done up-front at compile-time. At the other extreme, you may as well interpret rather than compile - and some reflection-like designs do use a kind of special-purpose interpreter. I may be biassed by thinking C++ and LLVM. – Steve314 Nov 4 '11 at 23:04

How do we deal with it when people regurgitate this dogma?

When a person tells you that she doesn't want to use goto, it doesn't mean anything with no further explanation. In fact, it may mean plenty of things:

  • goto is evil because my college teacher told me that it is evil, and this teacher is always right.
  • goto is evil because Jon Skeet told this once somewhere on Stack Overflow.
  • goto is evil in OOP because it breaks the flow of the application, which makes it more difficult to maintain, refactor and debug.
  • goto is evil; I don't know why but I believe people would consider me smart if I repeat what I've read somewhere or heard from a more experienced developer, even if I don't understand what I'm talking about.
  • goto is evil because its usage is prohibited in the coding practices of our company.
  • etc.

So yes, some people would stupidly repeat that goto is evil because somebody said it, but they don't care about what was said exactly, by who, in which context and for which language. To deal with those people,

  • if you can, try to force them to explain their assertion. Chances are, a junior developer who learned that goto must be dead doesn't really understand why, and will never be able to explain it.
  • if you can't (either because this person is your boss, or whatsoever), ask them to rewrite your code without using goto, singleton or reflection, and asset the quality (performance, readability, maintenability, etc.) of both versions.

In all cases, remember than there are cases when somebody shortcuts a long explanation into "goto is evil", because the discussion itself is not interesting and will not bring anything at all.

Example 1: on a project, I had a few hours discussion with my colleagues on stored procedures. It was decided to not use them for this project. At all. Because there are serious reasons to not use them in this case. If another developer joins this project tomorrow and starts to ask everybody why are we against stored procedures, we'll not discuss it, we'll not repeat all the arguments, because we don't have time for that.

Example 2: in our coding style guidelines, curly bracket must be on the same line in JavaScript, but always on a new line in C# and PHP. We will not discuss that with new developers. Never. Because we need an uniform codebase, and we are not intended to rewrite all the code we have every time a new developer arrives.

share|improve this answer
12  
Good points, but I would counter that any time you make a standard you should also record the reason why the standard was made. This serves two purposes: (1) educating newcomers, and (2) letting future participants know why a decision was made, and by extension, when the original reasons no longer apply and the decision can be safely reversed. – Scott Whitlock Nov 4 '11 at 18:51
1  
(+1) You really word it right what i really wanted to express. It is not about <code>goto is evil</code> it is about your understanding of why <code>goto is evil</code>. – Dipan Mehta Nov 4 '11 at 19:13
9  
So you become one of those shops where there are apparently arbitrary prohibitions with no reasons given? And no way to revisit those prohibitions if the circumstances change? The road to the Daily WTF is paved with such decisions. – David Thornley Nov 4 '11 at 19:24
2  
@David Thornley The prohibitions are not described as arbitrary. If you do not understand the reason for something, that is a fact about your own mind. That is not a fact about the project. I think I understand what MainMa is saying; he doesn't want to debate this topic again with new developers. – Jeremy Nov 4 '11 at 19:32
12  
Refusing to debate something and refusing to explain it are two different things. I expect to be given a reasonable explanation for policies and standards, even if they are not up for debate, because I am a professional not a five-year-old. – OrbWeaver Nov 4 '11 at 20:31
show 1 more comment

Rebutting the specific points:

No concept is harmful in itself.

It's not the concept that's harmful. Inappropriate use of a concept, tool, or technique can be very dangerous indeed.

Asserting one of the aforementioned is harmful is similar to saying that "a hammer is dangerous"

You seem pretty sure about that. Have you considered that in some cases the advice you get might be more like saying "a poorly engineered piece of artillary is dangerous?" In other words, while there may be legitimate arguments for using a feature that many consider "dangerous," the arguments for avoiding that feature may be well considered and substantially stronger than the arguments for.

It so happens that I really love goto, singleton, and reflection.

My advice here would be to avoid mentioning that as an argument in favor of using those features, particularly in an interview or code review. Because really: What's love got to do with it?

Beyond that, you should devote some thought to why you really love goto, singleton, and reflection. Is it because they're convenient? Can you appreciate the kinds of problems that each can cause? If you understand both the the benefits and the risks, you're in a pretty good position to make an informed decision. However, you should also make sure that you understand the risks from other people's perspectives and be able to work around them. To an organization with a large code base, the benefit of banning use of goto anywhere in their code may outweigh the benefit of using it in the occasional spots where it might help. You need to be able to deal with that restriction.

So I pose a question to the open minded amongst us, how do we deal with it when people regurgitate this dogma?

You're not winning any points for objectivity here.

What if it's a really good place to use a singleton, goto, or reflection, and then some non-thinker comes along and flames me for it?

If you can make a valid argument that your implementation is superior according to whatever metrics and standards are in play, then you should get to do things your way. If you lose the argument, then you should willingly adopt the superior method. And be careful tossing phrases like "non-thinker" around lest you be put in that very same box.

Example 1: Consider for a moment that you found a library called flimflamlib. It seems to do exactly what you need, and after reading the documentation you totally grok the whole concept behind the library. A few days after you start using flimflamlib in all your stuff, several senior developers tell you that they've looked at flimflamlib, and while they agree that it appears to be both highly useful and highly useable, it is in fact not just a piece of junk, but an unfixable and dangerous piece of junk.

What do you do? Do you label these nay-sayers non-thinking half-wits and disregard their advice? Do you go on using flimflamlib because, after all, it does what you want and you don't see why these scaredy cats should make you do things the hard way? Or do you take a hard look at flimflamlib, try to see things from their perspective, and reassess your use of it?

Example 2: Many companies have coding standards and/or style guides. Sometimes, these documents impose blanket prohibitions on certain techniques, patterns, features, etc. Google's C++ Style Guide is a great example. It says things like "We do not use Run-Time Type Information" and "We do not use C++ exceptions". It doesn't say "carefully consider the risk of _ and use your best judgement," but that doesn't mean that the document is dogmatic. Indeed, each rule in the document is accompanied by the rationale for the rule. You're welcome to disagree with the rules, but you're not welcome to disregard the rules when you're writing code for the organization.

In summary: Are there any practices that you would consider to be genuinely dangerous and/or ill-advised? What would you say to someone who disagrees with you?

share|improve this answer

I think there are three different and common situations:

  1. Business Decision - Sometimes it may be a wiser business decision (you know, the ones paying you) to do A instead of B. It may be cheaper, or it may mean shipping whereas an alternative may put you too far behind schedule. In these situations, its best to look at the long term costs versus the short term gains. Keep personal opinion out of this decision.

  2. Best tool for the job. - Sometimes it does make sense to use such things... just be sure you can defend your argument. Some people are not open minded, and always think in black or white: "I was told never to use [blank]". Try and convince them.

  3. You could be wrong - Keep this in mind too. There are, and probably will be cases where you will be making a bad decision. Sometimes its good to have that other guy saying "never use [blank]" and actually listening to him argue why you shouldn't do it. He could be right. As techies, we can naturally be bias towards things we like. It's hard to fight this.

To deal with it, consider why you are doing it, and whether or not its actually the right decision. It's not always a black and white decision, nor should it be. (robots would then replace us).

Hope this helps!

share|improve this answer

Mostly it's a question of context. If it's your software then do as you like with it. A lot of the issue with Goto is that it is often poorly used and particularly in object oriented programming it is seen as evil because it tends toward violations of the Encapsulation principle that helps OO programming work well. The malice toward singleton is similar in that it introduces a kind of global state into the program. This again can break encapsulation.

Keep in mind, the rules of OO are there to help you. But many people don't really understand the core concept or the rationale behind them. Having programmed some in Objective-C I too have a soft spot for reflection but it's widely misunderstood and should only be used when it's truly useful or the overhead doesn't matter.

As the Doctor said once, "Good men don't need rules. Today is not the day to find out why I have so many." In the end, it comes to down to experience and overall skill. If you are truly skilled then you can probably do whatever you want and make it work. However, if you are working with a team or don't truly understand something, it can be more dangerous. There's nothing worse than partial knowledge masquerading as complete.

share|improve this answer

I think it's better to base decisions on understanding than any kind of dogma.

At the same time:

  1. I'm pretty sure it's been at least 10 years since I had any reason to use an actual goto. That depends a little on how dogmatic you are though -- I've certainly used break statements (thinly disguised gotos) and exception handing (disguised goto with extra baggage added).
  2. Although I can imagine situations where one would be useful, I'm fairly sure I've never used a singleton in any real code.
  3. Although I have used reflection, when I have it's been (at least in my estimation) a pretty crappy kludge that I used because it happened to be quick and easy under the circumstances at hand. In every case, there was an alternative that was clearly preferable that wouldn't have used reflection. Much like singletons, I can imagine cases where it might be otherwise, but I'm pretty sure I've never encountered one in real code.
share|improve this answer
Gotos still have one valid use case: Situations where the looping decision is made in the middle of the loop. Sure you can come up with other approaches but I still feel Goto is the clearest here. – Loren Pechtel Nov 4 '11 at 23:40
Singletons have valid use cases: Access to resources that are inherently unique, or the controller arbitrating access to a pool of resources. If you want lazy initialization (say, it's expensive and not always needed) it's the best answer. – Loren Pechtel Nov 4 '11 at 23:44

Never let go of your common sense. Each of these dogmatic principles has situations where it applies, and situations where it doesn't. You need to be able to decide what is best, and if that means somebody gives you a flame, that's part of the risk you take. Fortunately, some of these issues have hard measurable effects, and you can demonstrate them (even if you can't always convince people).

If I can just give examples from my own experience:

  • I've been called the anti-profiling evangelist, and I try to show what I (& others) think is a better method, not in ease of use, but in speedup factors achieved. When speed is what is needed, that outweighs ease of profiling. Sometimes this point is hard to convey.

  • Ages ago, frustrated at the difficulty of writing UIs, a technique occurred to me that reduces the coding effort by about an order of magnitude. It was based on a control structure that I dubbed differential execution. I've implemented it many times in different frameworks, and it lets me create nice reactive UIs that "just work" with a fraction of the effort one might expect. Do I get flak for it? You bet. Have I won converts? Some, though not really. But the ratio of coding effort to functional requirements is easily demonstrated.

  • Also ages ago, I worked in computer integrated manufacturing, a field heavy with asynchronous protocols, parallel task scheduling, etc. The code people were writing for this was, to my mind, horrendously complicated. I came up with a domain-specific-language for it, implemented as C-macros, that shrunk the code, coding effort, and bugs by about an order of magnitude. The problem with this was (horrors) I had to embed goto statements in some of the macros. That's a good way to get yourself classified as a nut.

So that's the way in this business. Dogma is usually based on some good reason, but real progress may require going against the dogma.

share|improve this answer

The problem with singletons, gotos, and reflection is that their well-understood pitfalls mean that they should only be used when they are the most reasonable solution to the problem at hand, and we know from experience that they are used much more frequently than that in practice. The result is that experienced developers treat them with initial suspicion. Less experienced developers sometimes dismiss them completely in a misguided attempt to emulate their wiser colleagues.

If I check in some code that uses reflection, singletons, or gotos then I am going to have thought it through and concluded that it really is the best solution I can imagine. I'll be prepared to defend the solution. I fully expect that anyone reviewing the code would be skeptical at first glance, as they should be. I am happy to hear other opinions, but an unelaborated "reflection is bad" would not go down well. It is not always bad. The question is whether it is a good or bad way to solve this problem.

(There are more reasons not to use reflection than performance, BTW. It can mask unwise dependencies and make it more difficult to do static code analysis. If you use your singleton to store application-wide state like a huge global variable, then I am not going to be happy about that either. I won't even touch goto except to say that there are good times to use it, but they don't come up every day.)

share|improve this answer

These things are somewhat language dependent; for example in T-SQL GOTOs in stored procedures are pretty standard for exception handling, and they are the only way to break out of a while loop.

Singletons are actually quite good in older languages like C++ where ,given the amount of space in good books that is devoted to them, I don't think that they are Anti-Patterns. However, in more modern languages like C# then it is better to use an Inversion of Control container to manage the singleton instance (rather than building it into the class itself).

Reflection is amazingly powerful; but in general if you can do something without it, then you should. There are a lot of things that you need to do that require it. My main issue with reflections is that because you are essentially working "Black Ops" you break a lot of the refactoring tools built into the IDE. That is a bigger killer for me than it being slow.

In general, be pragmatic :)

share|improve this answer
+1 for "In general, be pragmatic." – Daniel Pryden Nov 4 '11 at 19:58

The point of general rules (e.g. "X is evil") in respect to concrete problems is directing your efforts to directions, that are likely to yield the cleanest concrete solution. They are not suitable to act as sole measure of a concrete solution's quality. You can't discard a solution using X merely on such a general rule. You can discard it with a better solution not using X, which is very likely to exists and which is what you should have looked for in the first place.

If you're in a situation, where apparently using a frowned upon shortcut yields a measurably or plausibly significant advantage (code reduction by 90% would be one :D) over the best solution you've been able to engineer without resorting to it, then just use it. There's hard evidence to justify it, and therefore it's objectively better.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.