If considered harmful?


Yeah, so true! Especially for simple tasks automation. Using Moose for basic administrative scripts is fun! :)


We also need object oriented bash and object oriented makefile syntax. :)
 
Last edited by a moderator:
Most retarded campaign ever.. I mean seriously.


I understand the need to eliminate the possibility of nulls, but the guy makes a case that if statements clutter the code, but he says using polymorphism doesn't.. Sure it cleans up the section where an if statement would be, but you need to write twice as much code using polymorphism techniques to do the same thing as a simple if/else if/ else statement.


sorry I don't buy it.
 
Not sure I understand this. If you want to eliminate IF clauses then you need some other sort of decision making, and the compiler will just break those down into compare/branch at some point, just the same as if you used an IF. It's the same for GOTO - the compiler doesn't magically stop using jump instructions if you stop using GOTO.


Colour me confused by all this.


D.
 
If its not a performance issue wich it dosnt seem to be then its a matter of taste.


The if statements is a LOT easier for me to read and understand, his example of polymorphism look like object-C to me, wich I hate with a passion, hate with a PASSION! My brain is cooking just thinking of it, I just cant read that type of code, it sure dosnt come natural for me and I doubt its something I could ever get used to.
 
Oh man, before you can even try to get at what point it is they're trying to make this website has so many red flags..


1) No real explanation on the front page that summarizes the problem


2) Pushing it forward as some kind of significant movement, focusing on their passion instead of technical merit


3) This is the real killer: saying that this is relevant information for business analysts, managers, and QA - all people who generally don't know how to program yet have influence over how you do your job. Teaching these people simple dogmatic rules for determining how your code is "wrong" without even understanding why is an absolutely terrible idea. This is entirely opposed to any notion of enhancing critical thinking.


These kinds of smug movements that focus on some kind of intellectual superiority and one true path are quite off-putting...


That said, if you try to look at what they're actually pushing it's what you'd expect - if is not ACTUALLY universally bad but is just misused. If they wrote some articles about specific examples (not sweeping generalizations) and some pragmatic alternative approaches, along with analysis of why it improved things it would inspire some good food for thought. Instead we get this sensationalist bullshit... Thing is, I'm pretty sure they're not really being totally serious here, but it's not hard to see how people won't get that.


As for your friend's blog post.. the example he gives is total bullshit and his arguments are mostly subjective. His "new" code only shows a tiny part of what he'd actually have to program - not only does he not show where all those different methods (and classes no less) are defined but he doesn't show how the factory chooses the right class in the first place. The latter point being especially key since that's probably done by using the exact same if-determination used in the original form. Of course, if the same if determination is used in several places then this can be a win, but he didn't express that, and surprisingly he didn't even list this as the advantage. There are of course other ways to factorize code, like putting that if in a method...


Polymorphism replaces direct conditionals with indirect calls. This has implications for both code-style/readability and performance. Of course he doesn't mention performance at all, which is absolutely inane. Pushing (possibly complex) conditional paths onto a different functions iterated through indirection is just another caching technique and serious performance-minded programmers think about this all the time. Like with all caches one big factor is how much it has to change. If bar changes all the time and is in a performance critical piece of his code he's going to be fucked.


Where someone starts preaching design patterns you can be pretty sure that there's a healthy amount of dogmatic preaching behind it. Ironically, he asserts that polymorphism is the cornerstone of most design patterns when the design patterns book says from the offset that most OOP techniques are suited to construction instead of inheritance (polymorphism implies inheritance)
 
Last edited by a moderator:
What Exophase has summed up here is a nice way to look at this critically. It seems that it's pushing OO code where none is needed, so that the code looks neat in a text editor.


I actually experienced this recently - my code uses a couple of CASE (switch) statements to branch to handlers of different tokens; three so far - one CASE for symbols (addition, subtraction etc), one for functions and one for keywords (in this case, a keyword is like a procedure with no return result and when done ends a statement, a function is used in an expression and stacks a result).


I replaced the CASE for keywords, which contained about 200 elements with a LUT of addresses to call based on the keyword ID - instant speed up, and massively more readable code.


Spurred on by this, I did the same thing for functions, which resulted in a similarly sized LUT and gained a further speed up, and again more readable code.


The reason I did this was because I examined the assembly output of the compiler, and it was a mass of conditional branches one after another - it would run through them all until one branched. The new way is better and generates just four instructions - basically a read from a calculated offset in memory and a jump to the result. Much better.


Then I tried to do the same for the Symbols case, which contains just 20 elements and found that my app's performance just ground to a halt. Turns out that the overhead of a CALL to a value read from a LUT and then a RET to the main loop is greater than no CALLs at all with all cases handled within that loop and near jumps around the loop as each handler is very small.


So that part of the code is very much harder to read, but a hell of a lot faster.


So yes, as Exophase states, it's all very well having nice code to look at, but it's not guaranteed to do the job any faster.


D.
 
I think I've figured out their issue (or one of their issues) with if statements after a lot of thinking... but I see a problem with their problem.


They show an image of the following example on their front page:



Code:
// Bond class

double calculateValue() {

   	if(_type == BTP) {

    	return calculateBTPValue();

   	} else  if(_type == BOT) {

            	return calculateBOTValue();

          	} else {

            	return calculateEUBValue();

          	}

}



The first thing I saw that was wrong with this was that it's absolutely horribly indented and not very well spaced, but on closer inspection, it looks like their problem here is making a generic method that checks a state attribute and calls the correct method based on that. Now, I'm not very familiar with Java at this point and don't know if there is any other way that's simple. In Python, I would actually do something like this:





Code:
class Bond(object):

	def __init__(self):

    	self.calculate_value = calculate_BTP_value


	def calculate_BTP_value(self):

    	do_stuff()

    	return stuff()


	def calculate_BOT_value(self):

    	do_stuff()

    	return other_stuff()


	def calculate_EUB_value(self):

    	do_stuff()

    	return third_stuff()


# Example usage

if __name__ == '__main__':

	foo = Bond()

	print(foo.calculate_value())



This is simply because it's easier in Python than making a fourth "calculate_value" method and figuring out what to do based on a variable. But AFAIK, Java doesn't just allow you to stuff anything you want into a variable like that (much less call a variable like a function/method), and I'm pretty sure C++ doesn't. I don't know if something like this is possible, but just because something is possible doesn't make it better.



Back to that mess of a code, it's a lot less of a mess if you write it normally, with an accepted indentation style:



Code:
// Bond class

double calculateValue() {

	if (_type == BTP) {

    	return calculateBTPValue();

	} else if (_type == BOT) {

    	return calculateBOTValue();

	} else {

    	return calculateEUBValue();

	}

}



And it looks even better if you just take out the unnecessary braces:



Code:
// Bond class

double calculateValue() {

	if (_type == BTP)

    	return calculateBTPValue();

	else if (_type == BOT)

    	return calculateBOTValue();

	else

    	return calculateEUBValue();

}


(As an aside, I absolutely despise that coding style of putting the else statement on the same line as the previous if statement's closing brace. It's horrendously ugly! C-style syntax looks much nicer to my eyes!)


EDIT: Why is all my code being shown with indents of multiples of 8 spaces...? It actually makes the Python code you see completely invalid and everything else unreadable. Oh well... I guess you'll just have to quote my post to see the actual code that I wrote instead of the indent rape that the code tag resulted in...
 
Last edited by a moderator:
Disclaimer: It's morning, I'll still try to make sense.


Clarification: the thread title is a humorous reference to all those "X considered harmful" essays. Note that if is never "considered harmful" in any of the associated texts.


Seems Exophase and ZXDunny have actually grasped what this whole thing is about. To quote anti-if school's web page

Like the Anti-IF Campaign, the goal of this school is not to propose the elimination of the IF statement from programming languages :), but to propose new, concrete programming techniques that enable software to grow in an effective, enjoyable, and conscious way.

It's not saying if should not be used. If is targeted because the programming methodology problems targeted by this campaign usually show up as if statements in cases which should be handled differently.


I'll give a concrete example from some of my recent code:


Look at the getCallback method in this class. For some time the function just returned null when there was no callback registered for the given ID. This resulted in null checks everywhere the method was used, eg. a lot of ifs that actually had nothing to do with what the program was supposed to do. So I created a singleton object that implements the same interface but by definition does nothing. Instead of returning null when there's no callback to return, I return this empty callback object. Now when I use the getCallback method I don't need to check for nulls anymore. Instead I can just execute the returned callback and never have a NullPointerException.


The problem wasn't the if-statements. It was avoiding doing proper structure by conditioning, which resulted in a ton of if-statements. Of course this is just an example with Java/null stuff, but I think it demonstreates how I perceive this campaign. By demonizing (tongue-in-cheek) if-statements it draws attention to where and how ifs are used and if they could be replaced with better structure.


onpon4: How do you choose what to assign to the calculate_value member of Bond? If it's with an if-block, it seems you're doing virtual functions manually :)
 
onpon4: How do you choose what to assign to the calculate_value member of Bond? If it's with an if-block, it seems you're doing virtual functions manually :)

You just assign the correct method. Functionally, it's no different than choosing what to assign to the _type attribute in the Java code given. In Python, any variable can be called like a function, and you can store just about anything (including a function or method definition) in a variable, so it's easier that way.

Look at the getCallback method in this class. For some time the function just returned null when there was no callback registered for the given ID. This resulted in null checks everywhere the method was used, eg. a lot of ifs that actually had nothing to do with what the program was supposed to do. So I created a singleton object that implements the same interface but by definition does nothing. Instead of returning null when there's no callback to return, I return this empty callback object. Now when I use the getCallback method I don't need to check for nulls anymore. Instead I can just execute the returned callback and never have a NullPointerException.

This isn't a problem with "if" statements, though. It's a problem with returning NULLs, which results in a requirement for "if" statements.
 
You just assign the correct method. Functionally, it's no different than choosing what to assign to the _type attribute in the Java code given. In Python, any variable can be called like a function, and you can store just about anything (including a function or method definition) in a variable, so it's easier that way.
Yes, I know how python works, but shouldn't you just do three subclasses with a unique calculate_value method for each? Because as I see it, you're just doing your own flavor of virtual functions by hand instead of using the built in system.

This isn't a problem with "if" statements, though. It's a problem with returning NULLs, which results in a requirement for "if" statements.
Isn't that what I said in the next paragraph?
 
You just assign the correct method. Functionally, it's no different than choosing what to assign to the _type attribute in the Java code given. In Python, any variable can be called like a function, and you can store just about anything (including a function or method definition) in a variable, so it's easier that way.
Yes, I know how python works, but shouldn't you just do three subclasses with a unique calculate_value method for each? Because as I see it, you're just doing your own flavor of virtual functions by hand instead of using the built in system.

I suppose so, if the "type" can never change. That's not really specified, so I didn't think about it. But in that case, the problem isn't using "if" statements, it's using an attribute that isn't appropriate when it really should be a subclass. The image with the original code I mentioned circled the "if" statements in red to point them out.

This isn't a problem with "if" statements, though. It's a problem with returning NULLs, which results in a requirement for "if" statements.
Isn't that what I said in the next paragraph?

Well, it just doesn't seem to be what this anti-if campaign is talking about.


If you are right about what the "anti-if" campaign is talking about, then they aren't criticizing what they say they are, and they're all over the place.
 
I suppose so, if the "type" can never change. That's not really specified, so I didn't think about it. But in that case, the problem isn't using "if" statements, it's using an attribute that isn't appropriate when it really should be a subclass. The image with the original code I mentioned circled the "if" statements in red to point them out.
To clarify, you're referring to this example. It isn't visible from the header snippet image (visible on every page), but you see from the full example that they've actually changed it to work using subclasses and polymorphism in their solution.

Well, it just doesn't seem to be what this anti-if campaign is talking about.


If you are right about what the "anti-if" campaign is talking about, then they aren't criticizing what they say they are, and they're all over the place.
Well, that might be true.


A part of why I created this thread was to see how others reacted to it, because after reading all of the available material I was still a bit confused as to what they were exactly saying. I understood many points (that I've explained here), but somehow the big picture- if there is one -has so far eluded me. I think I have the basic idea, but I wanted to see if people here saw what I did or if I was alone with my interpretations :)
 
This campaign attempts to draw attention to itself by utilizing a controversial, ridiculous statement. It's unneeded to phrase it like this and uninformed people might take it too literally.


That blog post of your friend is already a good example of someone who doesn't understand the message properly and starts misrepresenting the campaign with stupid, unclear and probably wrong examples.
 
We all should all just program in Brainfuck
default_ph34r.png'
and :angry: and forget about it.


EDIT: Can't believe I overlooked that. Too bad it's been quoted several times.
 
Last edited by a moderator:
Yes you are right. I haven't played around with it for a while.
 
Back
Top