私は廃止された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提供する一方で、字句スコープの関数定義を提供するという事実です。動的スコープは、内部的に間接に依存しているため、再帰をサポートします。