labelsとfletの違い

labelsは主に関数定義を入れ子にしたい場合に用いますが、fletというものもあるみたい。
外側(defun)と内側(labels,flet)の関数名が同一であった場合、内側の関数で再帰呼び出しをすると果たして誰にお呼びがかかるのか。labelsとfletはその時の振る舞いが異なるらしい。
labelsはあくまで自分自身。fletは外側の関数を呼び起こす。

;; labels
CL-USER> (defun foo (x)
           (format t "YesWeCan")
           (if (> x 0)
               (labels ((foo (x)
                          (format t "!")
                          (if (> x 0) (foo (1- x))) ))
                 (foo x) )))
FOO
CL-USER> (foo 5)
YesWeCan!!!!!!
NIL


;; flet
CL-USER> (defun bar (x)
           (format t "YesWeCan")
           (if (> x 0)
               (flet ((bar (x)
                        (format t "!")
                        (if (> x 0) (bar (1- x))) ))
                 (bar x) )))
BAR
CL-USER> (bar 5)
YesWeCan!YesWeCan!YesWeCan!YesWeCan!YesWeCan!YesWeCan
NIL