Friday, March 23, 2012

Dart Switch

‹prev | My Chain | next›

There are several places in my Dart code that could benefit from a good switch statement. The question is, does Dart have a good switch statement?

In my simple canvas player animation, I respond to event key codes with a series of if statements:
attachMover(me, context) {
  // Move on key down
  document.
    on.
    keyDown.
    add((event) {
      String direction;

      // Listen for arrow keys
      if (event.keyCode == 37) direction = 'left';
      if (event.keyCode == 38) direction = 'up';
      if (event.keyCode == 39) direction = 'right';
      if (event.keyCode == 40) direction = 'down';

      if (direction != null) {
        event.preventDefault();
        me.move(direction);
        draw(me, context);
      }
    });
Assigning direction in each of those if statements feels un-DRY. I would prefer assigning the direction variable once—to the result of a switch statement:
      String direction = switch(event.keyCode) {
        case 37: 'left';
        case 38: 'up';
        case 39: 'right';
        case 40: 'down';
      };
Only that does not work in Dart.

When I run that statement, Dart informs me that:
Internal error: 'file:///home/cstrom/repos/dart-book/book/includes/animation/main.dart': Error: line 65 pos 26: unexpected token 'switch'
      String direction = switch(event.keyCode) {
                         ^
So it seems that I am stuck setting the direction inside the case statements just as I did with the if statements:
      String direction;
      switch(event.keyCode) {
        case 37: direction = 'left';
        case 38: direction = 'up';
        case 39: direction = 'right';
        case 40: direction = 'down';
      };
I suppose that is a slight improvement over the equivalent if statements—at least with switch, I no longer need to check event.keyCode on each line.

So yes, an improvement except that it does not work. Working is kind of a big deal.

The crash message:
Exception: 'file:///home/cstrom/repos/dart-book/book/includes/animation/main.dart': Switch case fall-through at line 69.
Stack Trace:  0. Function: 'FallThroughError._throwNew@127eafe4' url: 'bootstrap' line:595 col:3
 1. Function: '::function' url: 'file:///home/cstrom/repos/dart-book/book/includes/animation/main.dart' line:69 col:9
 2. Function: '_EventListenerListImpl@33cc944a.function' url: 'dart:html' line:8653 col:35
Fallthrough? You mean that I have to break each statement in the switch()?:
      String direction;
      switch(event.keyCode) {
        case 37: direction = 'left'; break;
        case 38: direction = 'up'; break;
        case 39: direction = 'right'; break;
        case 40: direction = 'down'; break;
      };
Indeed, that is exactly what I have to do because, not only does that compile again, but also my player animation is again working:

And then:

But in the end, I think I prefer if-statement:
      if (event.keyCode == 37) direction = 'left';
      if (event.keyCode == 38) direction = 'up';
      if (event.keyCode == 39) direction = 'right';
      if (event.keyCode == 40) direction = 'down';
The equivalent case-statement-break buries the assignment inside too much code:
      switch(event.keyCode) {
        case 37: direction = 'left'; break;
        case 38: direction = 'up'; break;
        case 39: direction = 'right'; break;
        case 40: direction = 'down'; break;
      };
I really do not care for that trailing break. It obscures the intent of the code (the direction assignment), decreasing long-term maintainability. I suppose that I could move it to a separate line, but my switch() statement already has two more lines of code than the equivalent if-statement structure.

The only time that I can think to use the switch statement in Dart code is when I have significant, multi-line calculation to perform for each case. Even then it might be better to break those mulii-line statements out into separate functions.

Which begs the question: is there a use-case for Dart's switch()? Unless I can think of one, I may give it a miss in Dart for Hipsters.


Day #334

2 comments:

  1. Hi Chris,

    Here's the bug for you to star: http://code.google.com/p/dart/issues/detail?id=2047

    ReplyDelete
  2. Hi Chris,

    From my point of view, I wouldn't really see a place for this one in dart for hipsters as switch is quite a common thing in js or java, it seems from what I've read that people want to avoid the switch statement and I'm not the right one to argue whether to use it or not, I use it sometimes (have used it and will probably still use it), I guess it depends on the situation, switch can come in handy in some cases as far as Im concerned :)
    Cheers

    ReplyDelete