flip[1, 1, Unevaluated[s]]
s
(* {{-1, 1, 1, -1}, {1, 1, -1, -1}, {-1, -1, 1, -1}, {-1, 1, -1, 1}} *)
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}};
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.