Maxima lambda
不评估其体内的任何表达式,因此f
不进行评估(至g
)。这就是您所看到的行为。我认为这样做的动机是lambda
body 可能包含在某些变量具有值之前不会产生预期效果的表达式,例如length
, for ...
, print
, etc.
您可以通过替换到正文中来获得预期的行为。这里有两种方法可以做到这一点。第一个使用函数subst
我认为这可能是最明显的。
(%i1) X(f):= subst ('f = f, lambda([x,y],x*f(x,y)));
(%o1) X(f) := subst('f = f, lambda([x, y], x f(x, y)))
(%i2) X(g);
(%o2) lambda([x, y], x g(x, y))
(%i3) X(g)(z, t);
(%o3) z g(z, t)
第二个使用函数buildq
这实际上是一个替换函数,它引用(不计算)要替换的表达式。
(%i4) X(f) := buildq ([f], lambda ([x, y], x*f(x, y)));
(%o4) X(f) := buildq([f], lambda([x, y], x f(x, y)))
(%i5) X(g);
(%o5) lambda([x, y], x g(x, y))
(%i6) X(g)(z, t);
(%o6) z g(z, t)
最后,如果你有兴趣创作lambda
更频繁地使用求值表达式的表达式,您可以为此创建您自己的 lambda。我会称之为evlambda
here.
(%i11) evlambda (a, b) := apply (lambda, [a, b]);
(%o11) evlambda(a, b) := apply(lambda, [a, b])
(%i12) X(f) := evlambda ([x, y], x*f(x, y));
(%o12) X(f) := evlambda([x, y], x f(x, y))
(%i13) X(g);
(%o13) lambda([x, y], x g(x, y))
(%i14) X(g)(z, t);
(%o14) z g(z, t)
这里的关键是evlambda
被定义为普通函数,因此对其参数进行求值。所以到时候lambda
被申请;被应用,b
已被评估,因此它包含g
.
请注意,这evlambda
不会做任何有用的事情length
, for ...
, and print
,这是可以预料的。
(%i15) foo : evlambda ([l], 1 + length(l));
length: argument cannot be a symbol; found l
-- an error. To debug this try: debugmode(true);
(%i16) bar : evlambda ([n], for i thru n do print (i));
Unable to evaluate predicate 1 > n
-- an error. To debug this try: debugmode(true);
(%i17) baz : evlambda ([x], print (x));
x
(%o17) lambda([x], x)
(%i18) baz(5);
(%o18) 5
最后一张,与print
, 评估print
when baz
被定义(所以x
是输出),但是当baz(5)
被评估——这种行为是可以预料的,因为evlambda
评估其论点。