语言之间递归处理的差异

时间:2011-11-15 12:48:18

标签: javascript python ruby recursion lisp

以下是一些不同语言的代码段。

有问题的函数double来自SICP,例如。 1.41。

Lisp的:

(define (double f) (lambda (x) (f (f x))))
(define (inc x) (+ x 1))
(((double (double double)) inc) 5)

的Python:

def double(f):
  def result(x):
    return f(f(x))
  return result

def inc(x):
  return x + 1

double(double(double(inc)))(5)

使用Javascript:

var double = function(f) {
  return function(x) { return f(f(x)) };
};

var inc = function(x) { return x + 1  };

(double(double(double(inc))))(5);

红宝石:

double = lambda {|f| lambda {|x| f[f[x]] } }
inc = lambda {|x| x+1 }
double[double[double[inc]]][5]

如果我不是疯了,这些函数应该做同样的事情并返回相同的结果。 但是,lisp版本返回21而其他版本返回13.你能解释一下这个区别吗?我错过了什么吗?

2 个答案:

答案 0 :(得分:10)

如何调用方案代码中的函数与其他函数不同。等效的python是:

double(double(double))(inc)(5)

简而言之,方案代码创建了一个应用另一个函数16次的函数,并将该函数应用于inc。 python创建的函数应用inc 8次;其他人的工作方式与python相同。

如果为中间步骤引入名称,差异可能会更清楚一些。在计划中:

(define quadruple (double double))
(define hexadecuple (double quadruple)) ; hexadecuple may not actually be a word... 
(define add16 (hexadecuple inc))
(add16 5)

我希望这是正确的语法;自从我用方案做了一些事以来已经有一段时间了。

在python中:

add2 = double(inc)
add4 = double(add2)
add8 = double(add4)
add8(5)

答案 1 :(得分:2)

为了完整起见,这是一个固定的Ruby版本的样子:

double = ->f { ->x { f.(f.(x)) }}
inc    = ->x { x.succ }

double.(double.(double)).(inc).(5)