News for hackers. Stuff that matters.
Re:IF-less programming by raverbashing on Friday December 28, 2012 @07:40AM (#4977452)
This is getting ridiculous

" ifs are a smelly thing in a Object Oriented language."

What's smelly is such a absurd assumption. Yes, let's replace every small decision in our program with inheritance and another level of abstraction, that will work out swell

Please go read an Assembly manual because you have obviously forgotten what a computer is and does

And then we end up with unmaintainable systems with a class hierarchy higher than the Empire State.

Of course, as mentioned, replacing an if with a "software structure" (like pattern matching in an functional language) is beneficial, but to call it a code smell is ridiculous

Re:IF-less programming by revscat on Friday December 28, 2012 @09:20AM (#4977730)
> And then we end up with unmaintainable systems with a class hierarchy higher than the Empire State.

Perhaps, but I would rather have testable code than untestable code that is nothing more than a series of unnecessary, nested if blocks. We have all seen code that has a structure like

    if (depObj1.isSomething()) {
        if (depOboj1.getAttr() == CONST1) {
            // Do something
        } else if (depObj1.getAttr() == CONST2) {
            // Do something different
        }
     } else if ... {
        // repeat with minor differences
     }
Most of the time the above structure can be abstracted. Abstracting It also has the benefit of making this code more testable: you don't have to set up many different objects, just one.

The OP is correct: in OO languages if statements are a code smell. Like all smells, though, they are not hard and fast rules, but rather indicators that things could probably be done better. No one, certainly not OP, is recommending abandoning if statements. What he is recommending, and I agree with, is that they can and should be avoided, and certainly not turned to as a primary tool in the toolbelt.

Re:IF-less programming by pacala on Friday December 28, 2012 @10:10AM (#4977946)
As long as there is a mechanical transformation from one style to another, this is not abstracting, is merely shifting the syntax.

You do introduce more named test points, but you risk of creating too many tests at a too small granularity, that will only slow you down for no good reason. Consider using a code coverage tool to help you navigate all the branches, without explicitly naming them.

Keep in mind readability. Jumping around source files is costly on the reader, don't break the flow if you don't have to.

Re:IF-less programming by raverbashing on Friday December 28, 2012 @09:31AM (#4977772)
It's irrelevant if you're using ifs or different objects, the number of conditions/tests needed for what you are testing is the same.

Now, you could make depObj1 of type Obj1 and Obj2 to replace the if, which may simplify testing because the method is "simpler" in Obj1/Obj2/ObjBase but in the end it isn't!

Why? Because your test of Obj1/2 has to take care of their dependency to ObjBase. It's usually a dependency hell, needing lots of workarounds to test properly.

Re:IF-less programming by aardvark179 on Friday December 28, 2012 @09:49AM (#4977860)
I might agree if that type of if statement only appeared at one point in the code, but there're normally several scattered around which all have to be updated when obj3 is introduced. Also introducing a class hierarchy often makes it easier to move responsibilities between objects as the code evolves.

For example I recently did some work on a graphics library which had a lot of ifs to do with line and fill styles. By changing those into an inheritance hierarchy I found a couple of places where clauses had been missed and so fixed some bugs, but more importantly when we needed to add new fill styles which were more complicated to draw it became very easy to turn the fill style objects into fillers which had all the responsibility for filling paths, not simply setting the graphics state.

Re:IF-less programming by raverbashing on Friday December 28, 2012 @02:14PM (#4979026)
Yes, there are situations where changing the structure of the code is better than having an 'if' like the example you gave.

But this doesn't mean that it's better to completely eliminate ifs

Re:IF-less programming by alisnic on Friday December 28, 2012 @07:49AM (#4977481)
> "ifs are a smelly thing in a Object Oriented language."

It is partially my fault because I failed to express what I really ment. English not my native, so sorry.

What I really ment in this sentece is "why using (a lot of) ifs can be a bad practice in a Object Oriented language"

Re:IF-less programming by raverbashing on Friday December 28, 2012 @07:51AM (#4977486)
Ok, with that I can agree.

Or maybe better: how can ifs be replaced (sometimes) using OO principles

Re:IF-less programming by jeremiep on Friday December 28, 2012 @08:53AM (#4977650)
My take on why ifs are "bad" is that they are statements, just like for, while, switch and others. Being statements they can't be composed as you would do with expressions.
Re:IF-less programming by dragonwriter on Friday December 28, 2012 @12:38PM (#4978539)
That's not universally true; there are languages where if is an expression rather than a statement (e.g., Ruby.)
Re:IF-less programming by ufo on Friday December 28, 2012 @01:21PM (#4978761)
Most languages have a ternary if operator like (?:). I don't see how this is such a big issue.
Re:IF-less programming by meaty on Friday December 28, 2012 @08:03AM (#4977528)
To be honest, most of the ifs I write are usually error handling conditions so I sort of agree with the principle.

If you've been writing OO code for 10-15 years, you evolve into a model which is pretty if and block free. It just sort of happens one day. It isn't decomposed into millions of classes either - just a data model and some kind of effector such as specification/Builder/visitor. SRP only needs to go as far as method really as well.

I don't use functional pattern matching either.

If your code reads like math, I expect that its probably done right.

Re:IF-less programming by sp4rki on Friday December 28, 2012 @10:13AM (#4977961)
I know that this isn't probably the case you speak of when you say "If your code reads like math, I expect that its probably done right.", but I have a huge tendency to minimize code size by converting everything to "math". I converted a few hundred lines of C# code full of if statements made by a junior dev into this (more or less):

  var minutesToAddToAlert = (timeToAddInMinutes) + (900 * ((timeToAddInMinutes + 
                            (currentTimeOfDayInMinutes - 510)) / 540)) +
                            (2880*(((currentTimeOfDayInMinutes + (1440*dayOfTheWeek)) + 
                            ((timeToAddInMinutes) + (900 * ((timeToAddInMinutes + 
                            (currentTimeOfDayInMinutes - 510)) / 540))) ) / 7200));

  var nextAlertDate = currentDate.AddMinutes(minutesToAddToAlert);
There is definitely a lot more to it than just this, but I don't like blocks of code that don't fit on my vertical 24 inch screens. So I always end up converting "logic" (if's and else's) to math. It's a pet peeve of mine (as is overusing ternary operators as my own personal way of doing haiku), and while I certainly decrease the vertical size of the code itself, it makes it a hell of a lot harder to understand for everyone else. I then have to write comments explaining what stuff like this does, and those comments can get rather obtuse depending on the time of day.

Everyone winces when they see my commits with this message: "Math. Converted X and Y to M-A-T-H. Math. :D"

Re:IF-less programming by meaty on Friday December 28, 2012 @11:24AM (#4978210)
I'd probably actually break it into TimeSpan arithmetic for the sake of clarity and the fact that it won't require comments or so many brackets:

  var accumulator = new TimeSpan();
  accumulator.Add(TimeSpan.FromMinutes(currentTimeOfDayInMinutes));
  accumulator.Add(TimeSpan.FromDays(dayOfTheWeek));
  // ... etc - can't be bothered to do the rest...
  var nextAlertDate = currentDate.Add(accumulator);
No magic numbers, no arithmetic and clear to anyone who understands the TimeSpan class (which is the all powerful lord of the fourth dimension in .Net).

Oh and I work on a 1280x800 screen on an old ThinkPad T61. If the function doesn't fit on that, I'm concerned :)

Re:IF-less programming by sp4rki on Friday December 28, 2012 @01:43PM (#4978886)
Oh I would definitely agree with you just based on the clarity it provides (not even taking into account code size or elegance), but my coworker couldn't use TimeSpan because of certain domain specific criteria so I took his word for it and didn't even give it any thought. I just asked him what the problem/challenge was, grabbed a piece of paper, and did it with math and then just copied it to the code. In my defense, while testing both methods my solution worked reliably, while his had some pretty weird results on some extreme edge cases. With the amount of nested If/Else's he probably missed a couple of things as has been discussed on this thread previously.

In my defense, moving the logic to a pure arithmetic solution resulted in a procedure that takes a bit less than one third of my screen, while the old one was at least 6 or 7 pages of scrolling through nested conditionals.

Re:IF-less programming by jeremiep on Friday December 28, 2012 @08:51AM (#4977646)
Agreed, I wouldn't call ifs a code smell but rather OOP itself a code smell.

In any decent language, if will be an expression, not a statement. There is no difference between if and a function.

Re:IF-less programming by meaty on Friday December 28, 2012 @11:44AM (#4978293)
Oh yes we all live in the land of the ideal where everything is functional and has no side effects of course and we're blessed with parenthesis.

There is a huge difference between an if and a function. Consider SICP where lazy evaluation is introduced (read it if you haven't). An if statement encompasses the lazy evaluation as a native concept whereas a function's arguments are always evaluated (assumption for now - please carry on reading).

So consider an if statement as a control flow structure which automatically supports lazy evaluation and leaves the return semantics up to the user. This abstraction is clean from the highest level, right down to the CPU which uses conditional branching to perform the if operation. There is a 1:1 match all the way down.

The function on the other hand does not natively support lazy evaluation and enforces the return semantics. You then have to apply a lazy evaluation mechanism over the top (another layer of abstraction!). This layer of abstraction conveniently ends up using conditional branching to perform the if operation when it gets to CPU level. There is not a 1:1 match all the way down.

Big hint there: your functional if at the end of the day is just a compiler abstraction over a state machine which uses ifs.

As for OO, the industry I think has decided who won that battle.

But alas, no religious war is required. Use what tools work for you.

Re:IF-less programming by raverbashing on Friday December 28, 2012 @02:26PM (#4979081)
But for functional programming there's lambda calculus. OTOH there's no "OOP" calculus

"your functional if at the end of the day is just a compiler abstraction over a state machine which uses ifs"

Yes, that's the 'sad' part of it. In the end there's the Intel/AMD/ARM chip and nothing more

Re:IF-less programming by Bootvis on Friday December 28, 2012 @09:07AM (#4977686)
In what languages is if a function?
Re:IF-less programming by jeremiep on Friday December 28, 2012 @09:22AM (#4977737)
In Haskell/Ruby/CoffeeScript: a = if b then c else d

In Lisp: (setq a (if b c d))

Only Lisp implements them as a function (more precisely, a macro), but to the programmer there's no difference between using if and calling a function.

Of course, they don't compile into function calls in assembly code :)

Re:IF-less programming by adobriyan on Friday December 28, 2012 @09:35AM (#4977793)
It is called "special form".

http://www.lispworks.com/documentation/HyperSpec/Body/03_aba...

IF can't be implemented as a function because of evaluation rules.

Re:IF-less programming by jeremiep on Friday December 28, 2012 @09:53AM (#4977875)
Ah, that is correct. You can't use if as a first-class function in Lisp.

I still thought you could pass macros around like normal functions in Common-Lisp. The Lisp interpreter I wrote for fun could do that since the function value is resolved before arguments are evaluated for late macro expansions.

Re:IF-less programming by Bootvis on Friday December 28, 2012 @09:47AM (#4977855)
Also R and I think were mostly in agreement here. However I'm of the opinion that more than just these languages (languages with lazy evaluation or macro's) are decent and that in for example Ruby there are differences between if and a function, as this example shows (my first lines of Ruby)

    def iff(cond, x, y)
      if cond then
        x
      else
        y
      end
    end

    puts iff(true, 1, puts('2'))
echoes

    2
    1
if may behave as a function, but you can't write a function that acts like if.

edit: R does have real lazy evalution, e.g.

    > iff <- function(cond, x, y) { if (cond) x else y }
    > iff(TRUE, 1, cat('foo'))
    [1] 1
Re:IF-less programming by philwelch on Friday December 28, 2012 @10:00AM (#4977909)
There is a difference to the programmer, and it's pretty important as far as "if" goes: if "if" were a function, its arguments would need to be evaluated before they were passed in, which defeats the purpose of "if", which is to conditionally execute only one branch.
Re:IF-less programming by tomjakubowski on Saturday December 29, 2012 @03:28AM (#4981523)
You did say that only Lisp implements "if" as a function, but I thought I'd share that in Haskell "if" is syntactic sugar for a case expression. That is:

  if x then y else z
is sugar for:

  case x of
    True -> y
    False -> z
There have been suggestions to replace this sugaring with a proper "if" function, e.g.:

  if :: Bool -> a -> a -> a
  if True x _ = x
  if False _ y = y
to remove arguably redundant syntax, but it seems unlikely that this change would happen. See more here: http://www.haskell.org/haskellwiki/If-then-else
Re:IF-less programming by tarabukka on Friday December 28, 2012 @09:35AM (#4977790)
If is an expression in a lot of languages. The syntax you describe is identical to the "ternary statement" in C-style languages.
Re:IF-less programming by jeremiep on Friday December 28, 2012 @09:43AM (#4977838)
The ternary is an expression, not a statement :)

You can write: a = b ? c : d; in C/C++, you can't write a = if(b) { c; } else { d; }.

Re:IF-less programming by tarabukka on Saturday December 29, 2012 @06:27AM (#4981805)
Oh, yeah. My mistake. Although what you describe is a lot more functional in style. You could probably emulate it in a language with higher-order functions.
Re:IF-less programming by entropy_ on Friday December 28, 2012 @09:21AM (#4977731)
LISP maybe?
Re:IF-less programming by salboaie on Friday December 28, 2012 @12:41PM (#4978551)
Right, object oriented is not everything, sometimes ifs or switches are just fine.

I would suggest that decision tables, rule engines, workflow, DSLs, even finite automaton and other abstractions etc are better than having many many objects that are avoiding ifs :)

Re:IF-less programming by Nitramp on Friday December 28, 2012 @08:50AM (#4977643)
Did you watch the linked talk by Misko?

This is not about getting rid of "if" (as he mentions in the talk), this is about structuring large software systems for maintainability, extensibility, testability, etc.

Re:IF-less programming by philwelch on Friday December 28, 2012 @02:34PM (#4979122)
That's not really fair. The whole point of OO (at least dynamic dispatch) is that the dispatch system itself can evaluate a type condition, so you can rest a lot of weight on that implicit condition rather than having to write your own. If you have too many conditionals, maybe you aren't using that enough. Likewise, if you have list comprehensions or at least higher level functions like map, reduce, and filter, having too many loops is a little questionable.

If we wanted to program in assembly, we would be programming in assembly.