3
$\begingroup$

For example, I defined a user function with a module and what this function does is take the values of two global variables ga and gb and write another two global variables gsum and gdiff with their sum and difference, respectively. How can I define a user function in the form

fun[a_, b_, sum_, diff_] := Module[ ...]

so that I can get gsum and gdiff written with the correct values when I call this user function by

fun[ga, gb, gsum, gdiff] 

Assume that ga=10 and gb=5.

I guess another way to put my question is, how to define a user function with not only input arguments, but also output arguments?

$\endgroup$
3
  • $\begingroup$ What you want is called "call by reference". You can find other questions regarding this topic using the search function. One example: mathematica.stackexchange.com/questions/17767/… $\endgroup$
    – Felix
    Jan 24, 2017 at 1:26
  • 4
    $\begingroup$ That is not a good way to program. Better be explicit always. Write your function to return the values needed. If you need to reset the global variabes, then write{a,b}=fun[a, b, sum, diff] and in fun at the end, return {a,b}. This way the function is clear what it is doing. Someone looking at this later, understand what it does. Setting/resetting global variables from inside modules can lead to problems and bugs. $\endgroup$
    – Nasser
    Jan 24, 2017 at 2:30
  • $\begingroup$ @Nasser AppendTo 0_o $\endgroup$
    – Kuba
    Jan 24, 2017 at 8:00

1 Answer 1

3
$\begingroup$

You need non-standard evaluation. To do that, give your function the attribute HoldAll. Here is an example.

SetAttributes[f, HoldAll]
f[a_, b_, sum_, diff_] :=
  Module[{s = a + b, d = a - b},
    sum = s;
    diff = d;
  ]

ga = 10; gb = 5;
f[ga, gb, ga, gb];
{ga, gb}

{15, 5}

$\endgroup$
5
  • $\begingroup$ @Kuba I edited this answer to address that. m_goldberg, I hope you don't mind. $\endgroup$
    – Mr.Wizard
    Jan 24, 2017 at 7:35
  • 1
    $\begingroup$ @Mr.Wizard well, that link is in opposition to: tutorial/Evaluation where they are part of standard evaluation sequence. $\endgroup$
    – Kuba
    Jan 24, 2017 at 7:37
  • 2
    $\begingroup$ @Kuba I never claimed the documentation was not confusing. ;^) That tutorial also has a section titled Nonstandard Argument Evaluation -- the terminology is suboptimal IMO. $\endgroup$
    – Mr.Wizard
    Jan 24, 2017 at 7:39
  • 2
    $\begingroup$ @Mr.Wizard. 1) I don't mind at all. Your edit certainly improves the answer. 2) The term "nonstandard evaluation" has a long history. It goes all the way back to Lisp of the late 1950s. Even the earliest versions of Lisp had a special form QUOTE that stopped evaluation of an argument. I think it may be considered the ancestor of the various Hold forms of Mathematica. $\endgroup$
    – m_goldberg
    Jan 24, 2017 at 11:12
  • $\begingroup$ @m_goldberg I did not know; thanks for the education. I wonder if The Standard Evaluation Sequence, which includes hold attributes as Kuba points out, should have been called something else? $\endgroup$
    – Mr.Wizard
    Jan 24, 2017 at 11:16

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