0

I found a workaround to make composite function, but I believe there should be a better way to do this:

? f = x^2
%1 = x^2
? g = x^3      
%2 = x^3
? x = g
%3 = x^3
? fog = eval(f) 
%4 = x^6
? x = 2
%5 = 2
? result = eval(fog)
%6 = 64

In this method, I need to assign x many times and I don't want to use eval function. The code is not readable and maintainable.

karakale
  • 126
  • 11

2 Answers2

4
  1. You can simplify Piotr's nice answer to

    comp(f, g) = x->f(g(x));
    

Indeed, you do not need to assign to the (global) variable h in the comp function itself. Also, the braces are not necessary for a single-line statement, and neither are type annotations (which are meant to optimize the byte compiler output or help gp2c; in this specific case they do not help). Finally the parentheses around the argument list are optional in the closure definition when there is a single argument, as (x) here.

  1. I would modify the examples as follows

    f(x) = x^2;
    g(x) = x^3;
    h = comp(f, g);
    
    ? h('x)     \\ note the backquote
    %1 = x^6
    ? h(2)
    %2 = 64
    

The backquote in 'x makes sure we use the formal variable x and not whatever value was assigned to the GP variable with that name. For the second example, there is no need to assign the value 2 to x, we can call h(2) directly

P.S. The confusion between formal variables and GP variables is unfortunate but very common for short names such as x or y. The quote operator was introduced to avoid having to kill variables. In more complicated functions, it can be cumbersome to systematically type 'x instead of x. The idiomatic construct to avoid this is my(x = 'x). This makes sure that the x GP variable really refers to the formal variable in the current scope.

K.B.
  • 861
  • 5
  • 14
2

PARI/GP supports the anonymous closures. So you can define the function composition on your own like this:

comp(f: t_FUNC, g: t_FUNC) = {
    h = (x) -> f(g(x))
};

Then your code can be transformed to a more readable form:

f(x) = x^2;
g(x) = x^3;

h = comp(f, g);
h(x)
? x^6

x = 2; h(x)
? 64

Hope, this helps.

Piotr Semenov
  • 1,761
  • 16
  • 24
  • Many thanks for reply. As a note, I couldn't print h(x) as (x^6) again after this line(x = 2; h(x)). If I change variable name x to y (y = 2; h(y) print(h(y)); print(h(x));) or not use variable name (print(h(2)); print(h(x))) while evaluation, then I can see (x^6) again – karakale Aug 09 '21 at 20:12
  • 1
    To clear the `x` variable you can use the built-in function `kill`. For example, `x = 2; print(h(x)); kill(x); h(x)` will print `64` and `x^6` as expected. – Piotr Semenov Aug 09 '21 at 21:31