2
$\begingroup$

I'm working on a package with a lot of functions using Module, which all begin by unpacking the arguments into local variables. I'd like to store this unpacking code in a separate function called Setup and just call it in each function, but the local variables don't make it out.

A simple example:

Setup := (z = x^2);

g[x_] := Module[{z},
Setup;
Return[z]
];

g[3]

returns z$2599 when I'd like it to return 9. My real Setup is much longer of course, which is why I'd rather recycle it than rewrite it in each function.

Is there an easy way to make this work?

Update: A less minimal example

Here's a slightly less minimal example that captures more of the real situation. In my real problem, the Setup code is about a page long. At this point, I'm too far into this to change how I store the z[i] to a list!

Setup := (
numX = Length[x];
Do[z[i] = StringLength[x[[i]]], {i, numX}]
)

g[x_List] := Module[{numX, z},
Setup;
Table[z[i], {i, numX}]
]

g[{"hi", "there"}] should return {2,5}.

$\endgroup$
7
  • 1
    $\begingroup$ Please,can you clarify the question ? What's wrong with something like: setup[param_(*if required*),x_]:=x^2; g[x_]:=Module[{ret,z}, z=setup[param,x]; ret=f[z](*if required*); Return[ret] ]; g[3] $\endgroup$ Feb 22, 2016 at 20:36
  • 1
    $\begingroup$ You're scratching your left ear with your right hand (Spanish saying) $\endgroup$ Feb 22, 2016 at 21:01
  • 1
    $\begingroup$ @Dr.belisarius, interestingly, there is the same saying in Russian. $\endgroup$
    – garej
    Feb 22, 2016 at 21:17
  • 1
    $\begingroup$ @garej I guess that's because of the gauge invariance of the human body :) $\endgroup$ Feb 22, 2016 at 21:19
  • $\begingroup$ @Szabolcs Out of curiosity, why shouldn't you use Return at the end of a Module? Even though unnecessary, it helps me easily spot what's being returned at the end of a long Module. $\endgroup$
    – Chris K
    Feb 22, 2016 at 22:16

2 Answers 2

4
$\begingroup$

The thing to do is pass the parameters to setUp and make that function hold its arguments.

SetAttributes[setUp, HoldAll]
setup[z_, numX_, x_] := (numX = Length[x];
  Do[z[i] = StringLength[x[[i]]], {i, numX}])

g[x_List] := Module[{numX, z},
  setup[z, numX, x];
  Table[z[i], {i, numX}]]

g[{"hi", "there"}]

(* Out[1016]= {2, 5} *)
$\endgroup$
1
$\begingroup$

Why don't you use a function for it?

setup[x_, y_] := {x^2 - y, y*x^3}
f[args___] := 
    Module[{u,v},
        {u,v} = setup[args];
        u + v
    ]

I showed this to prove that the code can be concise but I would write out the arguments of f explicitly as f[x_, y_] instead of f[args___] to restrict the forms that match.

$\endgroup$
8
  • $\begingroup$ The real Setup is more complicated and involves setting an a priori unknown number of local variables using DownValues (i.e. setting z[1], z[2], ... ). $\endgroup$
    – Chris K
    Feb 22, 2016 at 20:37
  • $\begingroup$ @ChrisK It sounds like you should update the question and explain the use case better (and also motivate why you need DownValues instead of an array). $\endgroup$
    – Szabolcs
    Feb 22, 2016 at 20:39
  • $\begingroup$ @ChrisK It is possible to splice that piece of code (Setup) directly into the definition of g, but that is an error-prone advanced operation that should really be used only as a last resort ... The topic is covered in some detail here. I would not go that route unless I am really really sure that there is no better alternative. $\endgroup$
    – Szabolcs
    Feb 22, 2016 at 20:47
  • $\begingroup$ Thanks for the leads. At this point I've got too much code to change how I store the processed values. $\endgroup$
    – Chris K
    Feb 22, 2016 at 20:50
  • 3
    $\begingroup$ @ChrisK How about something like this (untested)? pastebin.com/dVx0p2ph $\endgroup$
    – Szabolcs
    Feb 22, 2016 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.