ある要素の出現によって他の要素の扱いを変えたいループ

 リストに対して操作を行うときに、その要素によって次の要素に対する処理を変えたい場合、というのが存在する。例えば、和田研フォントキットでは最終的なアウトラインデータは((angle 1 2) (bezier 2 2) (bezier 2 3)(angle 1 1))みたいな感じのリストで出てくる。angleというのは端点をしめしており、bezierというのはbezier曲線の制御点を示している。((angle 1 1)(angle 1 2))であれば、(1,1)から(1,2)への線分となる。bezierはともかくangleはかなりミスリーディングな名前であると思うのだが、それについて詳しく思いの丈をぶちまけることはここではやらない。
 ここから先、angleはa,bezierはbと省略する。
 このデータをSVGで出力するときの事を考えると、angle要素は最初の一つはmove_to, それ以外は基本的にはline_toとなる。bezierはかならずa1 b1 b2 a2と、2つのbがaで挟まれた形で出てくることになり、1つめのbを見た段階でcurve_to b1 b2 a2を出力し、b2とa2に関しては単独での処理は行わない、という事になる。
 forでこれを書く事を考えると、

  for(i=1, i<length(point_list);i++)
    p = get_point(point_list, i);
    switch(p.type) {
       case angle:
          line_to(point_list, i); break;
       case bezier:
          curve_to(point_list,i);i+=2;
    }

 みたいな感じになると思うんだけど、この7行目でのi+=2がどうにも気に入らない。forを使って書く場合、iの値を変更するのはfor(init;condition;step)のstepの部分だけにしたい。
 結局、angleとbezierで処理の対称性がないというのが気に入らない部分な訳で、それを考えると以下のような第二案も考えられる。

  for(i=1, i<length(point_list);)
    p = get_point(point_list, i);
    switch(p.type) {
      case angle:
          line_to(point_list, i); i++; break;
       case bezier:
          curve_to(point_list,i);i+=3;
    }

 angleでi++してからbreakするようにした。これはこれで、forがイディオム的な書き方から外れるので気持ち悪い。これが再帰を使って書くとちょっといい感じだね、というのが示したかったんだけど、書いてて疲れてきたのでそれはまた後ほど。