Octave / Matlab - 尾递归lambda函数的尾调用优化

时间:2016-01-31 14:39:12

标签: matlab functional-programming octave tail-call-optimization

我正在尝试编写递归匿名函数,到目前为止对我有用的是使用Y组合器。

%{ Call lambda function with any number of arguments.  %}
call_ = @feval;

%{ Internal subroutine for function IF_.  %}
if__ = @(varargin) varargin{3 - varargin{1}}();

%{ If predicate PRED is true, evaluate thunk IF_CLAUSE.  %}
% { Otherwise, evaluate thunk ELSE_CLAUSE.  %}
if_ = @(pred, if_clause, else_clause) if__(pred, if_clause, else_clause);

%{ Determine if X is a cell array.  %}
is_cell_ = @(x) isa(x, 'cell');

%{ Call function FUNC with elements in argument list ARG_LS as arguments.  %}
apply_ = @(func, arg_ls) if_(is_cell_(arg_ls), ...
                             @() func(arg_ls{:}), ...
                             @() func(arg_ls(:)));

%{ Compute a fixed point for the function H.  %}
Y_ = @(h) call_(@(x) x(x), @(g) h(@(varargin) apply_(g(g), varargin)));

因此,例如,要定义阶乘,我们可以使用Y组合子:

make_fact__ = @(f) @(n, accum) if_(n == 0, @() accum, @() f(n - 1, n * accum))
fact__ = Y_(make_fact__)
fact_ = @(n) fact__(n, 1)
fact_(5)

注意上面定义的阶乘是尾递归。无论如何都要优化尾调用,这样尾递归函数不会为大N吹掉堆栈?

在互联网上搜索给我相同的Python问题(Does Python optimize tail recursion?),但我不能真正使用Octave / Matlab,仅使用匿名函数。

我还发现了一些关于蹦床的文章,我再次发现很难仅使用匿名函数来实现try-catch,这在蹦床的实现中是必需的。

谢谢!

0 个答案:

没有答案