# Passing variables by reference

GROUPS:
 George Woodrow III 2 Votes In C and other languages, I can pass a variable to a function by value or by reference. If, for example, I pass an array by reference, I can act on the array in place without creating a new cooy to return.I see no easy way to do this in Mathematica.Can this be done, and if so, how?Thanks.
3 years ago
7 Replies
 Simon Schmidt 1 Vote Have a look at Attempting to make an assignment to the argument of a function over at stackexchange.In short, you're looking for HoldAttributes[modifyInPlace]={HoldAll};modifyInPlace[arr_]:=(arr[[1]]=9)a={1,1,1,1};modifyInPlace[a];a(* a is now {9, 1, 1, 1} *)
3 years ago
 George Woodrow III 1 Vote Thanks. I'll check it out. My real function has several parameters, and has a return value. I'm assuming that HoldFirst will work if I only want to pass the first parameter by reference.It strikes me, though, that this construct is not good Mathematica practice.
3 years ago
 Sean Clarke 1 Vote Using HoldAll is generally perfectly fine in practice. What is more likely to be bad practice is the creation of a function like "modifyInPlace" which modifies its input. In pure functional programming languages, this is not allowed.Your question is very common for anyone coming from  a language like C/C++ to Java/Python/Haskell/Mathematica etc. Many worry that if they aren't passing a reference to a function, then they are being inefficient because in C/C++ that would mean they were copying. This isn't the case with these other languages. Typically what you'll want to do is write a function that takes in a list and, instead of modifying the list that was given to it, returns a new list that is an updated version of the previous list. I understand that coming from a C/C++ background this likely sounds insane and horribly inefficient, but it allows you to write pure functions which are easier to test and maintain.
 Thanks for all your help. I have some sample code: Dynamic[entE1]  Dynamic[entS1]  entE1 = 3000; entS1 = 0;  SetAttributes[setEnergy, HoldAll] setEnergy[x_, entE_, entShields_] := Module[{newE = entE, newS = entShields, tot},  tot = entE + entShields;  newE = (1 - x)*tot;  newS = x * tot;    (*       executing these lines updated variables passed.  numbers are passed, we get an error  *)  entE = newE;  entShields = newS;    Style[StringForm[    "percentage is is :  \r Ent Energy is \r shields: ",     NumberForm[x, 4], NumberForm[newE, 4], NumberForm[newS, 4]], 12,    Blue, FontFamily -> "Courier New"]]val2FromSlider[myX_] := Module[{limits}, limits = 1;  Slider[myX, {0, limits}]]showValue[x_] := Style[StringForm["value is :  ",    NumberForm[x, 4, NumberSigns -> {"-", "+"}]], 12, Blue,   FontFamily -> "Courier New"]{val2FromSlider[Dynamic[eEn]], showValue[Dynamic[eEn]], Dynamic[setEnergy[eEn, entE1, entS1]], Dynamic[entE1], Dynamic[entS1]}This is a toy example of what I want to do. There are separate functions. One does the UI part, using a slider to set a percentage. There is a function that uses the current values of entE1 and entS1 to cumpute new values of the variables using the percentage eEn.  The display code in setEnergy[] is there for debugging purposes.This code works as written.I tried to have setEnergy[] return the new values of entE1 and entS1, but if I did so, they were not dynamically updated. I tried wrapping Dynamic around the returned variables, to no avail. (I thought that this approach would work.)I tried some other variations without much success.As I said, this version works, and I can apply it to my real code. I would like to know if there is a more elegant solution.Thanks.