Constructing a function that declares some other function inside it's body?

Viewed 52

Sometimes I need to use a declaration of a function inside another function. For example, I made the following in Mathematica:

enter image description here

Ie: There is a function f and when I compute f[Cos], it declares h as Cos[x]. Observe that I can't do the same by computing f[x] because it does not recognize $x$ as a function, although I can circumvent that by using Mathematica's notation for pure function: f[#&], now it works perfectly fine.

I noticed I can do the same with Maxima:

enter image description here

Although I don't know how to do the f[#&] in Maxima. Ie: Tell Maxima "x" is a function just as I did in Mathematica. Is there a way to do the same in Maxima? Also If I try to compile:

enter image description here

Without asking it to compute g(x), f won't work in the same way it worked before. It's not clear to me why this happens.

1 Answers

:= always defines a global function, even if it's within another function or block. As it stands, when you call f twice, the second definition of g clobbers the first one -- you can't have two different g functions.

I think what you want is an unnamed function, lambda([x], ...). The tricky part is that the body of lambda is not evaluated, so when you write lambda([x], y(x)), the value of y doesn't appear in the result. There are a few different ways to achieve that; I'll describe one way using subst.

subst('y = something, lambda([x], y(x))) constructs an unnamed function and then pastes something into it, replacing y. The result is lambda([x], something(x)) which I think is what you want.

To put this in the framework you outlined,

(%i3) f(x, y) := block ([g: subst ('y = y, lambda ([x], y(x)))], [g, g(x)]);
(%o3) f(x, y) := block([g : subst('y = y, lambda([x], y(x)))], [g, g(x)])
(%i4) f(1/2, cos);
                                                   1
(%o4)                    [lambda([x], cos(x)), cos(-)]
                                                   2
Related