Re: Functions inside modules with external definitions
- To: mathgroup at smc.vnet.net
- Subject: [mg96512] Re: [mg96494] Functions inside modules with external definitions
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Sun, 15 Feb 2009 03:21:12 -0500 (EST)
- References: <200902140814.DAA17405@smc.vnet.net>
Hi, The difficulty you are having is due to the fact that the scoping constructs (Module in particular) tend to rename the bound variables when they feel a possibility for a name conflict. Perhaps, the question you are asking is this: how to define a local function with variables automatically bound to certain specific variables of an arbitrary expression on your rhs. If this is really what you want, the solution is to make the binding of the would-be-local function's variables happening outside of the lexical scope of the scoping constructs - in this case they won't be able to "spot" the conflict at their own binding time. Anyway, here is the code: In[1] = (* Auxilliary function *) Clear[optF]; optF[x_] := With[{xl = x}, Optional[Pattern[xl, Blank[]], xl]]; (* Bringing variable binding in the would-be-local function out of scope of enclosing Module *) Clear[makeFunction]; makeFunction[fn_, x_, y_, a_, b_, c_, rhs_] := With[{optx = optF[x], opty = optF[y], opta = optF[a], optb = optF[b], optc = optF[c]}, fn[optx, opty][opta, optb, optc] = rhs]; (* Finally, what you want: *) Clear[compute]; compute[expr_] := Module[{f}, makeFunction[f, x, y, a, b, c, expr]; f[k1, k2][.2, .3, .4]]; Test: In[2] = compute[expression] Out[2] = 0.2 k1^0.4 + 0.3 k2^0.6 I would also add that it would be less error prone to define your <expression> with SetDelayed rather than Set: In[3]=expression:=a x ^c + b y ^(1-c) And, finally, to wrap all your computation in a Block: In[4] = Block[{x,y,a,b,c},compute[expression]] Out[4] = 0.2 k1^0.4 + 0.3 k2^0.6, to protect your computation from possible global values that {x,y,a,b,c} may have. You can test that on different expressions the result will be accordingly different - perhaps this is what you asked for. Let me also remark that in general, playing with binding and breaking the binding scope (by separating the lhs and rhs into different parts of the program) is a pretty error-prone practice, and there should be good reasons for doing it - there almost always exist better design solutions. The whole fact that we have to "blind" the scoping construct means that we are going in directions where we will get no automatic support from the language. Regards, Leonid On Sat, Feb 14, 2009 at 12:14 AM, E. Martin-Serrano < eMartinSerrano at telefonica.net> wrote: > Hi, > > > > Please review the following and see weather my question has and deserves an > answer. It is a about defining functions local to modules but using > external > definitions of the right hand side of the local function and passed as > parameters to the module. > > > > > > expression = a x ^c + b y ^(1-c) (* or whatever expression *) > > > > Clear[f]; > > > > f[x_: x,y_: y][a_: a,b_: b,c_: c]:=Evaluate@expression > > > > ?f > > f[k1,k2][.2,.3,.4] > > > > (* Functions inside modules where the RHS of the function has been assigned > to a variable *) > > (* first form works as I expected, but uses an extrenal definition for a > local function (the name is local) *) > > > > m1= > > Module[{f}, > > f[x_: x,y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expression; > > f[k1,k2][.2,.3,.4] > > ] > > > > (* second form. I expected it worked as the one above but it does not; the > expression formed outside is assigned to a local variable with the same > name > *) > > > > m2 = > > Module[{f, expression = expression}, > > f[x_: x, y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expression; > > f[k1,k2][.2,.3,.4] > > ] > > > > (* third form. I expected it worked as the first one above but it does not; > the expression is assigned directly to a local variable *) > > > > m3 = > > Module[{f,expression = a x ^c + b y ^(1-c)}, > > f[x_: x,y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expression; > > f[k1,k2][.2,.3,.4] > > ] > > > > (* fourth form. I expected it worked as the first one above but it does > not; > the expression is assigned within the body of the module o a local variable > *) > > > > m4 = > > Module[{f,expr}, > > expr =expression; > > f[x_: x,y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expr; > > f[k1,k2][.2,.3,.4] > > ] > > > > (* My question is how to construct a function inside a module in manner > similar to the following *) > > > > expression = a x ^c + b y ^(1-c); > > mx = > > Module[{f,expression = expression}, > > f[x_: x,y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expression; > > f[k1,k2][.2,.3,.4] > > ] > > > > (* and working as the following works *) > > > > m1= > > Module[{f}, > > f[x_: x,y_: y][a_ :a,b_: b,c_: c]:=Evaluate@expression; > > f[k1,k2][.2,.3,.4] > > ] > > > > Many thanks > > > > > > E. martin-Serrano > > >
- References:
- Functions inside modules with external definitions
- From: "E. Martin-Serrano" <eMartinSerrano@telefonica.net>
- Functions inside modules with external definitions