Programming style abominations

Or wrap it up in a try … catch statement :slight_smile:


for(int i = 0; i < 100; i++)
{
	MIDDLE_LOOP: for(int j = 0; j < 100; j++)
	{
		for(int k = 0; k < 100; k++)
		{
			if (found(i,j,k))
			{
				doSomethingComplicated(a, b, c, d, e, f, g);
				break MIDDLE_LOOP;
			}
		}
	}
}

:smiley:
And for the record? Dijkstra’s original “Goto Considered Harmful” paper explicitly mentions early exits from loops as a valid use of the goto keyword in the absence of an alternate syntax for accomplishing the same thing.

squeegee, flag variables are ugly and error prone. They obscure the intended control flow and should be avoided.

As for try-catch, the problem is solved by using RAII. It gets a little uglier in Java, but it’s not that bad.

Frankly, error codes suck. They’re terrible. Nobody ever checks them properly and even if you do half of the time you have no clue how to deal with the error. Exceptions are a much cleaner solution to the problem.

No argument… but you’d consider a flag worse than a goto? I’d take the opposite stance, vehemently, unless there were a compelling reason and goddamn big comment over the code that does so.

I would absolutely consider a flag to be worse than a goto. Goto is not inherently evil. Judicious use of goto can improve the clarity of code, as in Shalmanese’s example. I’d bet that your real problem with goto is that all your life you’ve been told that goto is evil and that you should never ever use it. The problem with goto is that it can be used to create awful, awful code. But that’s hardly a problem restricted to goto and a blanket ban on goto in real code is not useful.

I guess we’ll just disagree then. I consider goto useful in real time control code (“shit, we lost contact with the device! arg!”), and very ugly in procedural situations. I can’t say I’d consider a flag as more obscuring of control flow than a goto that jumps across several layers of scope, abandoning things in its wake.

And please don’t infer what I’ve been told or not about style.

I didn’t realize C had labelled breaks, but if you insist on using the imperative for loop style for this, then I think Rysto’s labelled break solution is clearly the right way to do it. However, just for fun, here’s how I’d express it in Haskell:


--Here's the middle and last loop combined (the ones iterating over j and k)
--I'm assuming here that a through g are expressions involving i, j, and k
middleloop i
  = sequence (take 1 [doSomethingComplicated(a, b, c, d, e, f, g)
                       | j <- [0..99], k <- [0..99], found(i, j, k)])

--Here's the outer loop (the one iterating over i, 
-- which you seem to want to run through every i no matter what)
outerloop = mapM_ middleloop [0..99]


No gotos, no breaks, no flags.

It doesn’t. I was trying to make the point that goto isn’t necessary if you have alternate syntax for accomplishing the same thing.

Ah, I thought that might have been it. Rats, you got me all excited for a moment.

(But, yeah, arguing that these sorts of cases demand goto is like working in a language without in-built looping constructs and noting that your “while loop” problem demands goto, in all its glory; no, it doesn’t, it just demands some looping constructs)

What Happens To People Who Use GOTO

I don’t know… I think the arguments over syntax are a little silly. I’ve been writing and reading code for 25 years, in about a dozen different languages, written by hundreds of different software developers, each with their own style. Nothing wrong with that. Unless it’s absolutely egregious, it doesn’t bother me.

I used K&R braces for over a decade before moving to a company that was using C++ and had a culture that braces had to start a new line. I have good reasons to prefer K&R brace styles, but whatever. I switched to their style, got used to it, and no big whoop.

As software developers, I think we spend a little too much time arguing syntax, and probably too much time arguing about small details such as the use of flag variables and GOTO.

Far more important is the ability to design a decent algorithm, and to design a decent method. And to do decent architecture in the first place. If a coder clearly thinks through his design and comes up with an elegant program structure that is easy to use and understand, makes logical sense, and is efficient, I don’t really give a rat’s ass if he uses the occasional GOTO or wacky brace style.

I think we tend to argue about style a lot because it’s an easy thing to argue about. Simple concepts, easily described, commonly used. It’s our equivalent of arguing about Snap-On vs Craftsman. Fun, but ultimately rather trivial in the grand scheme of things.

I don’t think we can easily dismiss arguments over syntax as trivial.

Different people are affected differently when they see alternate syntax, and you, apparently are one of the people who are not bothered by it, and can adjust quickly.

However, for many people, once their brain gets used to a certain syntax style, it can do quick pattern recognition and parse the code you are reading very quickly.

If you change the syntax a bit, you then don’t use that sub-conscious pattern matching part of the brain to “take in” the code, and you must use your conscious part to process what you are reading. Invariably, this is much slower.

This is not restricted to software coding.

From what I know, if you submit a script for a movie or sitcom, it has to follow a very specific set of formatting rules. Not because if you change the spacing or the alignment you will make any difference to the story, but because people who read scripts day in and day out are used to a particular format, and this enables them to get through scripts much faster.

If you suddenly change the font, spacing, alignment, etc of the script, it will take them much longer to read it.

Now, there may be some people who can read the script with the same speed no matter what formatting it has, but I think these will be in the minority. For most people, it does matter, and it does make a difference in reading speed.

Plus,



if(bla) {
   foo;
}


is just plain ugly :slight_smile:

I very briefly tried something years ago with the horrifically Medusan C++ that I thought might have been useful but instead probably warranted the near-crucifixion I received for tying it: I defined explicit syntactical terms to braces so that the reader could figure out just where in any given code / data / object construction they were without having to back-trace through the nested braces.

It was essentially the same thing Taran describes.

No real “intervention” was called for; my colleagues simply screamed in anguish.

Never tried that again!

Please throw me into that briar patch! Holy Fuckin’ Shit, are you kidding me? I’d KILL thousands for code like that!

I once had the dubious “privilege” to be the sole person contractually hired to modify the code for the safety systems…

THE SAFETY FUCKING SYSTEMS

of several commercial nuclear reactors. Holy Bob how I wished I’d turned them down!

Over the course of hundreds of thousands of lines of PDP-11 assembler and FORTRAN, there were perhaps 50 lines of comments. Fifty lines!

And there was nothing written down outside the code, either.
Think about that as you go to sleep tonight!

“Too many comments”? Hah! There can be no such thing!

Except that you have to pass all the intermediate variables into middleloop so it would be more like:


--Here's the middle and last loop combined (the ones iterating over j and k)
--I'm assuming here that a through g are expressions involving i, j, and k
middleloop a b c d e f g i
  = sequence (take 1 [doSomethingComplicated(a, b, c, d, e, f, g)
                       | j <- [0..99], k <- [0..99], found(i, j, k)])

--Here's the outer loop (the one iterating over i, 
-- which you seem to want to run through every i no matter what)
outerloop = mapM_ (middleloop a b c d e f g) [0..99]


which was precisely something I wanted to avoid.

I think Sam makes a really good point here. Its fine to have preferences about brace styles and lots of other things, but at some point it becomes silly, and clinging to a style in the face of other people doing something different in the same code you’re working on is not productive, and in fact it’s often the opposite.

If you’re a professional working on a project with other people, your job is to follow the code “culture”, regardless of your likes or dislikes. If this means a different brace style than you’d prefer, or more white space, or variables declared with lined up tabs or not, well that’s not your choice. You’re a professional, so act like one: suck it up, do your job, and stop obsessing over trivia.

More than once I’ve seen a code check-in which consisted of some jackass reformatting a whole file to suit his style, while making one substantive change in a single function. The diffs go on for pages, and the real work that was done was obscured, and this numb-nutz used productive time to do brace masturbation. And not only that, but there’s now a single file that looks like “his” way, and the rest of product, a million lines of code, looks completely different. Thanks for taking a crap in the code base, Einstein.

Now, if you want to improve the code quality overall, you need to convince other people on the team about how much better “your” way is. It will be an uphill battle, and it’s likely they’ve had this discussion before, and will be bored to tears and feel your priorities are cockeyed. They may be right, but maybe at some point you bring the team around to your way of thinking (and probably get stuck with the job of fixing all that code to be “pretty”). Or you don’t and you move on to more productive pursuits. This is what professionals do.

This isn’t to say that coding conventions aren’t arguable, or that some styles don’t provide measurable benefits in productivity. Sure, they are, and they do. But that isn’t always going to be your call; you’re not an artist, you’re not a director – you’re an engineer, which means job #1 is pragmatism, which in turn means getting the job done with the appropriate amount (no more and no less) of effort.

So why do you let him check it in, then? Don’t you have peer review in your shop?

If one programmer craps in the code base, it’s because the rest of the programmers allow this to happen!

Ah, I had thought a b c d e f g were just expressions involving i, j, and k, not mutable variables. But, I don’t see what your rewrite accomplishes. If a through g have global scope, it’s exactly equivalent to what I wrote. If a through g are supposed to have some elided declarations local to outerloop, it’s exactly equivalent to just taking my code and putting a “let” before the definition of middle loop and an “in” after it. Wherever it is that a through g are supposed to have been declared, just sticking my definition of middleloop there will accomplish the same thing as your rewrite. I think perhaps you meant to do something else with your rewrite?

At any rate, my code, as written, still works perfectly well if a through g are supposed to be mutable variables. Take them as threaded through the monad outerloop acts on. Everything works out.

I didn’t. That’s precisely why I found it.

Not as ugly as:



if ( bla.hasValidSettingForPropertyNameDerivedFromBaseClassBThatIsASubclassOfA( bFlag_Param1 , bFlag_Param2 ) )
    {
        foo ;
    }