Shammer's Philosophy

My private adversaria

Lispではcontinueを使えない?

continueとは

ループ処理の途中で、処理を一巡送りするキーワードでContinueというのがある。例えば、Javaでは以下のように使用する。

public void do()
    for( int i = 0 ; i < 10 ; i++ ){
        if( i == 5 ){ 
            continue;
        }
        System.out.println(i);
    }
}

こう書くと、i==5のときはcontinue以下の処理は何も実行されずにi==6の処理が続行されるが、Lispではこのcontinueに相当する処理はない。Lispでこれを実現するには、

  • (unless (equal i 5) ...) というように書く
  • tagbodyを使用する

のいずれかになる。

unlessを使用した例

上記と同じ処理をLispで書くと以下のようになる。

? (do* ((i 0 (incf i)))
       ((< 10 i))
    (unless (equal i 5)
      (format t "~A~%" i)))
0
1
2
3
4
6
7
8
9
10
NIL
? 

tagbodyを使用する

こちらはtagbodyを使用した例。

? (let ((i 0))
  (tagbody
   start
   (progn
     (incf i)
     (cond ((equal i 5)
	    (go start))
	   ((equal i 11)
	    (go finish))
	   (t
	    (format t "~A~%" i)
	    (go start))))
   finish
   (format t "Finish~%")))
1
2
3
4
6
7
8
9
10
Finish
NIL
? 

結論

やってみてわかったが、continueは別になくても困らない。ある特定の条件を満たした場合には何もしない、というように書いておけばそれで同じことを実現できる。書き方としては、tagbogyよりもunlessの方がシンプルそうだが、状況によってはtagbodyの方がいい場合もある、、、かもしれない。