Pari / GP: custom function as return value

I have a problem with user defined Pari / GP functions using user defined functions returning functions. Below is an example:

? f(x) = { (t) -> x + t }
%1 = (x)->(t)->x+t
? g(x) = { local(y); y = f(x); (t) -> y(t) }
%2 = (x)->local(y);y=f(x);(t)->y(t)
? h = g(2)
%3 = (t)->my(x=2);y(t)
? h(1)
  ***   at top-level: h(1)
  ***                 ^----
  ***   in function h: y(t)
  ***                  ^----
  ***   not a function in function call
  ***   Break loop: type 'break' to go back to GP

      

I was expecting to get h (1) = (g (2)) (1) = y (1) = (f (2)) (1) = 3. I am facing a limitation of first-class functions in Pari, or am I doing something wrong? If the latter, how do I fix it?

+3


source to share


1 answer


Note. The keyword local

limits your variables to dynamic scope. Make sure the guy y

from the same / outside scope is referencing the expected thing when calling the call h(1)

. In this case, the corresponding fix could be as follows:

?f = (x) -> { (t) -> x + t }
%1 = (x)->(t)->x+t

?g = (x) -> { local(y); (t) -> y(x)(t) }
%1 = (x)->local(y);(t)->y(x)(t)

?h = g(2)
%1 = (t)->my(x=2);y(x)(t)

?y = (x) -> f(x);
?h(1)
%1 = 3

?y = 1;
?h(1)
*** not a function in function call 

      

Alternatively, I highly recommend using static (lexical) scope for variables to simplify your code and eliminate associated dependencies. To do this, use a specifier my

. Take a look at the fixed code below:



?f(x) = { (t) -> x + t }
%1 = (x)->my(t);t->x+t

?g(x) = { my (y = f(x)); (t) -> y(t) }
%1 = (x)->my(y=f(x));(t)->y(t)

?h = g(2)
%1 = (t)->my(x=2,y=(t)->my(x=2);x+t);y(t)

?h(1)
%1 = 3

      

Note that it h

takes less time to evaluate the latest version . Also I recommend using the code style of the PARI / GP authors ( http://pari.math.u-bordeaux1.fr/pub/pari/manuals/2.4.2/users.pdf )

+3


source







All Articles