Maxima lambda
не оценивает ни одно из выражений внутри его тела, поэтому f
не оценивается (до g
).Это поведение, которое вы видите.Мотивация для этого, которую я вижу, состоит в том, что тело lambda
может содержать выражения, которые не имеют ожидаемого эффекта, пока некоторые переменные не имеют значений, например length
, for ...
, print
и т. Д.
Вы можете получить ожидаемое поведение, подставив его в тело.Вот два способа сделать это.Первая использует функцию 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
выражений с использованием вычисляемых выражений чаще, вы можете создать свой собственный тип лямбда-выражений для этого.Я назову это evlambda
здесь.
(%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 ...
,и 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
, когда определено baz
(таким образом, x
является выходом), нозатем не повторяется при оценке baz(5)
- такое поведение следует ожидать, поскольку evlambda
оценивает его аргументы.