'combinations whose operators are themselves compound expressions' 是可变函数的同义词吗?

Are 'combinations whose operators are themselves compound expressions' synonymous with Variable Functions?

对于这里缺少一些词汇,我提前表示歉意。通过 Structure and Interpretation of Computer Programs,有一个早期参考 'combinations whose operators are themselves compound expressions',例如:

(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))

其中组合 (if (> b 0) + -) 被评估为 +-,然后被评估为例如(+ a b) 如果 b 大于零。

我的问题是:这与变量函数(例如 in PHP), and how so? Also, do variable functions and this functionality differ from using Javascript-style object references 不同吗?

从 Lisp 的角度来看,这里的重要概念是一种语言是 'lisp-1' 还是 'lisp-2'。这两者之间的区别是:在一个看起来像函数应用程序的表达式中,代表要应用的函数的东西是如何评估的?

因此,在 Lisps 中,看起来像函数应用程序的东西看起来像列表:

(f a b ...)

当考虑这样的事情时,系统必须做三件事:

  1. 确定它函数应用程序(因此,例如,(if ...)不是,也不是宏形式);
  2. 如果是,计算函数及其参数;
  3. 调用该函数,将对其参数求值的结果传递给它。

(注意:我在这里假设了所谓的applicative-order评估:normal-order语言确实事情有所不同。)

问题是 (2) 是如何发生的。

  • A lisp-1 以与所有其他位置完全相同的方式评估这种形式的函数位置(第一个位置)。因此函数位置可以包含一个完全任意的表达式。所以 ((if add + -) 1 2) 非常好,例如 (let ((op ...)) (op ...))
  • A lisp-2 对函数位置使用一些特殊规则,特别是对于 lisp-2,符号的 'function value' 位于不同的命名空间中到普通值。这意味着那里允许的是 而不是 通用表达式,而是规则允许的任何内容。因此,例如,在 lisp-2 中,像这样的东西不起作用:(let ((op (lambda ...))) (op ...)),但像这样的东西 确实 起作用:(let ((car ...)) (car car)).

众所周知,Scheme 是 lisp-1,Common Lisp 是 lisp-2。

那么我认为回答您的问题的方法是认识到这个概念可以很好地应用于其他语言。

  • JavaScript 是 lisp-1,所以看起来像函数应用程序的东西的函数位置被正常评估。
  • Python 是 lisp-1。
  • 我不知道 PHP 是什么。

请注意,在这些语言中,你知道某个东西是函数应用程序的方式与在 Lisp 中完全不同,但重要的问题是,一旦你知道了,你如何评估函数位置?

在Scheme(SICP使用的)中,可以在函数位置使用变量。

首先我们尝试使用符号+作为函数:

尝试将符号用作函数

> (define foo '+)
> foo
+
> (foo 1 2)
Exception: attempt to apply non-procedure +

不幸的是,这不起作用:foo 求值为符号 +,这本身不是函数

使用函数对象

但这行得通:

> (define foo +)
> (foo 1 2)
3

这里foo设置为+的值,是一个函数对象。 foo 也将评估该对象。因此 (foo 1 2) 的计算结果为 3.

JavaScript中的所有函数都是变量,它允许运算符位置的表达式:

function plus (a, b) {
  return a + b;
}

plus; // => [Function: plus]

function minus (a, b) {
  return a - b
}

minus; // => [Function: minus]

function plusAbs (a, b) {
  return (b > 0 ? plus : minus)(a, b);
}

plusAbs(3, -3); // => 6
plusAbs(3, 3);  // => 6

var plus = 4;
plus; // => 4 (no longer a function)
plusAbs(3, 3);  // ERROR! 4 is not a function

正如 Scheme 一样,它 不会 评估为 plusminus,而是 plusminus 评估到。例如。 [function minus] 而不是 变量。

PHP中的函数不能通过名称这样完成,但是绑定到函数的变量:

function plusAbs ($a, $b) { 
  $add = function($a, $b) { return $a+$b; }; 
  $sub = function($a, $b) { return $a-$b; }; 
  return ($b < 0 ? $sub : $add)($a, $b); 
}
plusAbs(3, -3); // => 6

最接近的命名函数:

function add($a, $b) { return $a+$b; }
function sub($a, $b) { return $a-$b; }

function plusAbs ($a, $b) { 
  return call_user_func($b < 0 ? 'sub' : 'add', $a, $b); 
}
plusAbs(3, -3); // => 6

请注意,这不再具有运算符位置的表达式。