| Ilya Zakharevich on Mon, 22 Apr 2019 13:07:17 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: Creating inline closures |
On Sat, Dec 08, 2018 at 02:15:17PM +0100, Bill Allombert wrote:
> > Suppose I have a C function
> > GEN mysummand(GEN I, void *mydata);
> > It is completely unclear how can I make out of it something to
> > pass to (e.g.) somme() to make an analogue of
> > sum(I=1,3,mysummand(I))
>
> Hello Ilya,
>
> To help you to upgrade, I join a program that should do what you want.
>
> 1) use pari_add_module to add your functions to GP.
> pari_add_module(functions_ilya);
??? Why would I want to expose my function to the interpreter, if it
is not usable standalone?
> 2) use strtoclosure to create the partial function as t_CLOSURE object
> fun = strtoclosure("_ilya_mysummand",1,stoi((long)&mydata));
> This returns a t_CLOSURE x -> mysummand(x, &mydata)
It looks like a very strong overkill. As far as I can see, (1)+(2)
can be replaced by a call to snm_closure().
> At this point you can use the t_CLOSURE directly in functions like
> apply that need a true closure (code "G" or "J")
I do not care about these anyway…
> 3) for functions like sum that need a inline closure (code "E" or "I"),
> you need to create a gadget that will inline your closure inside the
> sum. The simplest is to use the GP compiler:
> sum_gadget = gp_read_str("(a,b,C)->sum(i=a,b,C(i))")
> and then use closure_callgenall to evaluate it with C set to your
> closure.
> s = closure_callgenall(sum_gadget, 3, stoi(1), stoi(3), fun);
Using a compiler is exactly what I want to avoid.
It looks like what I need is essentially a new function
snm_lex_closure() with exactly the same semantic as snm_closure(), but
taking the first n C-arguments not from GP-arguments, but from the
last n defined lexical variables. (So the produced function is 0-ary,
same as an inline closure.)
But thanks anyway,
Ilya
P.S. What does snm_ mean?