**update 11/17/13:** Added this example from Wagner book, on the danger of using `HoldAll`. This is a good reason why one should stick to default pass-by-value in Mathematica. Here is the example: ClearAll[p, inc, double, x]; SetAttributes[inc, HoldAll]; SetAttributes[double, HoldFirst]; inc[x_] := x = x + 1; double[x_] := x + x p = 4; inc[p]; (* this makes p=5 now *) double[p] (* this makes p=10 now *) gives as expected : (* 10 *) Now changing the call to emulate call by reference, and look what happens now: ClearAll[p, inc, double, x]; SetAttributes[inc, HoldAll]; SetAttributes[double, HoldFirst]; inc[x_] := x = x + 1; double[x_] := x + x p = 4; double[inc[p]] (* what do you think p will be after this? *) Gives (* 11 *) Clearly what happens, as the book says, is that in the second case, `inc[p]` was evaluated twice, and not one time as one would expect. Hence `inc[p]; double[p];` gave different result to `double[inc[p]]`. **Original answer** First method: Unevaluated ------------ Wrap the argument you want to pass by reference with `Unevaluated` flip[posX_, posY_, lattice_] := Module[{x = posX, y = posY}, lattice = ReplacePart[lattice, {y, x} -> -valueAtPos[x, y, lattice]] //. {{1} :> 1, {-1} :> -1} ]; valueAtPos[positionX_, positionY_, lattice_List] := Flatten[Take[lattice, {positionY, positionY}, {positionX, positionX}]] s = {{1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}}; Now flip[1, 1, Unevaluated[s]]; s (* {{-1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}} *) Disadvantages: You lose the ability to add type checking (as in adding `lattice_List` in the formal parameter, must write it as `lattice` only ) Second method: HoldAll ------------- Make the function itself HoldAll ClearAll[flip]; flip[posX_, posY_, lattice_] := Module[{x = posX, y = posY}, lattice = ReplacePart[lattice, {y, x} -> -valueAtPos[x, y, lattice]] //. {{1} :> 1, {-1} :> -1} ]; Attributes[flip] = HoldAll; valueAtPos[positionX_, positionY_, lattice_List] := Flatten[Take[lattice, {positionY, positionY}, {positionX, positionX}]] s = {{1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}}; now flip[1, 1, s]; s (* {{-1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}} *) Third method HoldFirst ------------ Move the one argument to be passed by reference to first argument and use `HoldFirst` ClearAll[flip]; flip[lattice_, posX_, posY_] := Module[{x = posX, y = posY}, lattice = ReplacePart[ lattice, {y, x} -> -valueAtPos[x, y, lattice]] //. {{1} :> 1, {-1} :> -1} ]; Attributes[flip] = HoldFirst; valueAtPos[positionX_, positionY_, lattice_List] := Flatten[Take[lattice, {positionY, positionY}, {positionX, positionX}]] s = {{1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}}; gives flip[s, 1, 1]; s (* {{-1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}} *) But I think, in the spirit of Mathematica programming and functional programming, is that one should not do these things. i.e. functions should not have side-effects. To modify something, write `newValue = foo[ oldValue ]` and pass things by value, which is the default. see also [passing-large-list-by-reference][1] and [does-pass-by-value-affect-the-performance-of-function-calls][2] [1]: http://mathematica.stackexchange.com/questions/19445/passing-large-list-by-reference [2]: http://mathematica.stackexchange.com/questions/20865/does-pass-by-value-affect-the-performance-of-function-calls