私は廃止されたelispマクロに慣れており、flet
に変更するように言われましたcl-flet
。しかし、この変更を行うと、一部のelispプログラムが機能しなくなりflet
、その理由は、とは異なり、cl-flet
再帰的な関数が許可されていないことに気付きました。たとえば、以下の関数を定義します
(defun show-problem-in-action (x)
(cl-flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
一つは取得しないエラーを呼び出すことにより、
(show-problem-in-action 0)
出力:1
「cl-flet-defined」関数factorial
は、「x = 0」の場合、それ自体を呼び出さないためです。しかしながら
(show-problem-in-action 5)
エラーを生成しますvoid-function factorial
。
一方、次のようなcl-flet
非推奨のマクロflet
で置き換える
(defun no-problem-with-deprecated-macro (x)
(flet (
(factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1))) )))
(factorial x) ))
再帰的な呼び出しを可能にします:
(no-problem-with-deprecated-macro 5)
出力:120
cl-flet
が機能しない場合、置換する代わりflet
に、再帰的に関数を呼び出すことができる最善の選択肢は何ですか?
flet
、cl-flet
再帰のサポートの欠如ではなく、flet
動的スコープの関数定義をcl-flet
提供する一方で、字句スコープの関数定義を提供するという事実です。動的スコープは、内部的に間接に依存しているため、再帰をサポートします。