Message Boards Message Boards

0
|
6763 Views
|
4 Replies
|
1 Total Likes
View groups...
Share
Share this post:

Using an Association to contain different equations within a Module

Posted 6 years ago

After much head scratching and experimenting, I've solved a particular problem - but I can't see why my first attempts did not work. So there's clearly something I'm not understanding here. Simplified code below:

myFuncA[xAssoc_] := Module[{},
  tmpFuncA[x_] = xAssoc[a];
  tmpFuncA[10]
  ]
myFuncB[xAssoc_] := Module[{},
  tmpFuncStr = xAssoc[a];
  tmpFuncB[x_] = tmpFuncStr;
  tmpFuncB[10]
  ]
myFuncC[xAssoc_] := Module[{tmpFuncStr},
  tmpFuncStr = xAssoc[a];
  tmpFuncC[x_] = tmpFuncStr;
  tmpFuncC[10]
  ]

myAssoc = <|a -> 1 + x, b -> 2 + x|>;
func[x_] = myAssoc[a];
func[10]
myFuncA[myAssoc]
myFuncB[myAssoc]
myFuncC[myAssoc]

I have an association with 2 simple equations in x. I can assign one of these 'a' to a function and then pass a value to it - func[10]. The output is as expected - 11. However, I wanted this to be used inside another function, hence myFuncA. This contains essentially the same code,however the output is now 1+x To get the correct result,I had to use an intermediate variable as in myFuncB which gives the correct - 11 - output. But being a mindful programmer, I like to keep the scope of temporary variables as limited as possible. So I wrote myFuncC. The output from this 1+x

myFuncB works but myFuncA does not.

And myFuncC breaks it again.

What am I missing here? There must be something about variable scope I am not getting. Can anyone enlighten me perhaps.

[Edit: Mathematica 11.2 on Raspberry Pi]

POSTED BY: Paul Scanlon
4 Replies
Posted 6 years ago

Many thanks for those replies, given me much more reading to do. Just want to add a few notes,in case it's of interest to anyone else. The Trace command is very useful (thanks Henrik), but can be a bit confusing for complicated functions. Where it's suspected a definition is in question,then the Information function - or ? - can be useful.

?tmpFuncA

Global`tmpFuncA
tmpFuncA[x$_]=1+x

The x$_ indicating the issue. Quite why, I'm still trying to figure.

I now agree with Eric that passing 'pure' functions is better. However, I did solve the myFuncC by using TranditionalForm as below

    In[180]:= myFuncC[xAssoc_] := Module[{tmpFuncStrC},
  tmpFuncStrC = TraditionalForm[xAssoc[a]];
  tmpFuncC[x_] = tmpFuncStr;
  tmpFuncC[10]]

myAssoc = <|a -> 1 + x, b -> 2 + x|>;
myFuncC[myAssoc]


Out[182]= 11
POSTED BY: Paul Scanlon

This is a little ugly, but it works:

func[y_] := Module[{temp},
  temp[x_] = ToExpression[StringReplace[ToString[y], "x" -> ToString@x]];
  temp[10]
  ]

testing:

func[x+2]
12
POSTED BY: Eric Smith

What I would recommend, is changing your association to pass pure functions. Relying on the same dummy argument names across modules is not a great idea. So change it to something like...

func3[y_] := Module[{temp},
  temp[x_] = y[x];
  temp[10]
  ]

But your "y" needs to be pure function...

func3[Function[x, x + 2]]
12
(*or*)
func3[#+2&]
12
POSTED BY: Eric Smith

Hi Paul,

in those cases the function Trace can be useful:

enter image description here

So it becomes obvious why the second case is not working: It is the assignment

tmpFuncA[x$_]=1+x

I guess MM is doing this to avoid conflicts because the outer layer is a delayed assignment.

Hope that gives you an idea, regards -- Henrik

POSTED BY: Henrik Schachner
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract