Reputation: 2599
In Maple (version 14, if it matters), I define a procedure that uses a globally-defined expression in maple, but when I go to code generation, it assumes the variable is not what I am expecting.
a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)
What I expect is a C function with the expression inserted into the code, but instead I get...
double p (double x, double y)
{
return(a);
}
Upvotes: 1
Views: 764
Reputation: 7246
This is one of those 'by design' things. Even though it may seem awkward to you in this particular situation, this lexical scoping behaviour on (modern) Maple's part is more often an advantage and is quite deliberate. And there are several ways around it, to get your expectation.
The simplest workaround, in this case, might be just this:
restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;
p := proc(x::float, y::float) return a end proc;
CodeGeneration:-C( subs('a'=a,eval(p)) );
double cg (double x, double y)
{
return(x + y * x);
}
What is accomplished above is that subs('a'=a,eval(p))
forms a new instance of the proc p
in which a
is replaced in the proc body by the explicit value of a
(ie. what a
evaluates to). Note the output of the following, and compare with the output above when p
was initially created,
subs('a'=a,eval(p));
proc(x::float, y::float) return x + y*x end proc;
Keep in mind that, even though it's not apparent in this very simple workaround example, the given substitution for the global names x
and y
into that copy of p
is actually playing a tricky game with Maple's scoping rules. In more complicated scoping situations this might go amok. But if what you really want is inlining, then you can get that in more explicit and controlled ways. Look at the echoed output of p
when initially created in this next example,
restart:
a := proc(A,B) option inline; A+B*A: end proc;
a := proc(A, B) option inline; A + B*A end proc;
p := proc(x::float, y::float) return a(x,y); end proc;
p := proc(x::float, y::float) return x + y*x end proc;
CodeGeneration:-C( p );
double p (double x, double y)
{
return(x + y * x);
}
Hopefully, those two approaches are enough to see you through.
Let's briefly return to your original example, just to notice something. The global names x
and y
as they appear in the value of a
are very much not the same as the names of the two formal parameters of the initially created procedure p
. They are quite different instances of what merely appear to be the same name. Consider,
restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;
p := proc(x::float, y::float) return a end proc;
p(4.0, 5.0);
x + y x
Upvotes: 2