3
$\begingroup$

This question already has an answer here:

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$

marked as duplicate by Mr.Wizard Jan 24 '17 at 7:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\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 '17 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 '17 at 2:30
  • $\begingroup$ @Nasser AppendTo 0_o $\endgroup$ – Kuba Jan 24 '17 at 8:00
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$
  • $\begingroup$ @Kuba I edited this answer to address that. m_goldberg, I hope you don't mind. $\endgroup$ – Mr.Wizard Jan 24 '17 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 '17 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 '17 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 '17 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 '17 at 11:16

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