17

I wanted to know, how to evaluate multiple statements in a function in Mathematica.
E.g.

f[x_]:=x=x+5 and then return x^2

I know this much can be modified as (x+5)^2 but originally I wanted to read data from the file in the function and print the result after doing some data manipulation.

Szabolcs
  • 24,728
  • 9
  • 85
  • 174
mrig
  • 382
  • 1
  • 4
  • 21

3 Answers3

20

If you want to group several commands and output the last use the semicolon (;) between them, like

f[y_]:=(x=y+5;x^2)

Just don't use a ; for the last statement.

If your set of commands grows bigger you might want to use scoping structures like Module or Block.

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
  • 2
    I think one should localize variables regardless of the program size, since programs do evolve and unlocalized variables are an invitation for trouble. – Leonid Shifrin Nov 29 '11 at 20:49
8

You are looking for CompoundExpression (short form ;):

f[x_]:= (thing = x+5 ; thing^2)

The parentheses are necessary due to the very low precedence of ;.

As Szabolcs called me on, you cannot write:

f[x_]:= (x = x+5 ; x^2)

See this answer for an explanation and alternatives.


Leonid, who you should listen to, says that thing should be localized. I didn't do this above because I wanted to emphasize CompoundExpression as a specific fit for your "and then" construct. As it is written, this will affect the global value of thing which may or may not be what you actually want to do. If it is not, see both the answer linked above, and also:

Community
  • 1
  • 1
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • Wow, 30 seconds! I'll delete mine :) – Szabolcs Nov 29 '11 at 20:03
  • But only if you correct the `x=x+5` bit either by using another variable or `HoldAll` or something that avoids obvious errors! – Szabolcs Nov 29 '11 at 20:04
  • @Szabolcs oops! Speed has is failings. – Mr.Wizard Nov 29 '11 at 20:06
  • 2
    This is getting ridiculous. I wonder if Mr.Wizard has discovered the secret of time travel. – Heike Nov 29 '11 at 20:09
  • I think `thing` should be localized. – Leonid Shifrin Nov 29 '11 at 20:48
  • @Leonid please tell me if that addresses your concern. – Mr.Wizard Nov 29 '11 at 20:59
  • @Mr.Wizard Yes, it does, thanks. It is IMO ok to have the code like that exposed, as long as it is always stated what are the limitations and possible problems with it, right next to it (don't get me wrong, I am mostly concerned with new users here) – Leonid Shifrin Nov 29 '11 at 21:09
  • @acl it looks like you're due for your silver tag badge. Congrats! – Mr.Wizard Nov 29 '11 at 21:47
  • @acl I'm done for the day unless something *really* tantalizing comes up, and I happen to be here. – Mr.Wizard Nov 29 '11 at 21:51
  • @acl, congrats on the silver, and it is our goal to prevent our top users (myself included) from being able to answer anything without tripping over each other. That way, we can limit the number of badges handed out. Just remember, "we don't need no stinkin' badges!" (I apologize for the [pop-culture reference](http://en.wikipedia.org/wiki/Stinking_badges).) – rcollyer Nov 30 '11 at 16:17
  • @rcollyer thanks! it would still have been nice to be able to answer a question once in a while, though! – acl Nov 30 '11 at 16:23
  • @acl, I empathize with your plight. I hate being seconds away from posting an answer and having another one posted. A lot of times, though, I have better references (unless it is Leonid), so I leave my answer to compete with theirs. – rcollyer Nov 30 '11 at 16:26
  • @acl judging from the (lack of) votes for this answer, people may want to punish me for posting first, so posting your answer anyway gives them an outlet for votes. :^) – Mr.Wizard Nov 30 '11 at 16:49
  • @Mr.W yes, I wondered why your answer here got no votes (I didn't vote for any of them, now that I think of it!). looks like the number of votes is roughly proportional to the length of the (initial) answer. I have noticed something like this before. – acl Nov 30 '11 at 17:07
7

Several people have mentioned already that you can use CompoundExpression:

f[x_] := (y=x+5; y^2)

However, if you use the same variable x in the expression as in the argument,

f[x_] := (x=x+5; x^2)

then you'll get errors when evaluating the function with a number. This is because := essentially defines a replacement of the pattern variables from the lhs, i.e. f[1] evaluates to the (incorrect) (1 = 1+5; 1^2).

So, as Sjoerd said, use Module (or Block sometimes, but this one has caveats!) to localize a function-variable:

f[x_] := Module[{y}, y=x+5; y^2]

Finally, if you need a function that modified its arguments, then you can set the attribute HoldAll:

Clear[addFive]    
SetAttributes[addFive, HoldAll]
addFive[x_] := (x=x+5)

Then use it as

a = 3;
addFive[a]
a
Community
  • 1
  • 1
Szabolcs
  • 24,728
  • 9
  • 85
  • 174
  • thanks a lot. I think this will work. I feel that Mathematica Help is pathetic, they should make that more usable and userfriendly...other than that I like it. – mrig Nov 30 '11 at 11:46
  • 2
    @newGuy I find the Mathematica documentation excellent compared to most other programs I've seen. Enter `tutorial/SequencesOfOperations` in the doc browser and click the Virtual Book button. – Szabolcs Nov 30 '11 at 13:06