DEV Community

Discussion on: Juniors Literally Can't Write Switch Statements: What Senior PHP Developers Need to Focus On

Collapse
jbristow profile image
Jon Bristow • Edited on

DIGRESSION/SLIGHTLY OT, FEEL FREE TO DISREGARD

As a Senior Developer, I hate switch functions. (Especially if they don't auto-break.)

They were a mistake to add to C, especially with the fall through. It's a bad construct that unnecessarily simplifies an if/elseif/else construct while enabling mistakes and unclear flow.

They are doubly a mistake in "OO" languages. They encourage thinking that breaks the "Tell, don't ask" model.

Yes, they're old and they served their purpose when optimizing compilers weren't as good and disk space for storing source code was expensive. I say that we should avoid 'em and teach others to do the same.

(I do not argue that switch is sometimes easier to read than a forest of if/elif/else. I just think the dangers introduced by fall-through switches is too high to ignore.)

Collapse
robdwaller profile image
Rob Waller Author

I'll be honest with you, I've never really used them. I agree they don't seem to suit OOP and I'm not sure they can comply with the single responsibility principle.

Collapse
legosteen11 profile image
Wouter Doeland

They can be quite useful traversing through possible enum values. It kinda depends how the language implements switch functions. I program a lot in Kotlin and I like how they have implemented it (no need to break and you can use mutliple possible values which means no falling through kotlinlang.org/docs/reference/cont...)

Collapse
jbristow profile image
Jon Bristow • Edited on

Right, but only for simple things.

To me, especially with an OO design, I'd rather encourage:

// assume a calculator that only handles binary operators

Operator operator = Operator.parse("+"); //throws OperatorParsingException
operator.resolve(a, b);

Over

switch (operatorInput) {
  "+": add(a, b);
       break;
  "-": minus(a, b);
       break;
  default:
    throw OperatorParsingException(operatorInput);
}

Now, when we get back into functional, I'm not as confident in my design, but I think I would do it like this. (But the switch statement badness is not precisely involved anyway, I'm just thinking out loud here.)

(defmulti operator (fn [op a b] op))
(defmethod operator :plus [_ a b] (+ a b))
(defmethod operator :minus [_ a b] (- a b))

(operator :plus 5 6) ; =11
Thread Thread
legosteen11 profile image
Wouter Doeland • Edited on

Sure, but in the Operator#resolve function you will still need either an if or a switch statement. How I would do this in Kotlin:

fun resolve(a: Int, b: Int) = when(type) { // type is the operator type
        OperatorType.minus -> a - b
        OperatorType.plus -> a + b
    }

or:

fun resolve(a: Int, b: Int) =
    if(type == OperatorType.minus)
        a - b
    else if(type == OperatorType.plus)
        a + b
    else
        throw Exception("!?")

I think the first one is way more clear.