Message Boards Message Boards

GROUPS:

List parameter to function

Posted 10 years ago
3358 Views
|
4 Replies
|
0 Total Likes
|
I oviously don't understand how functions work.
I am trying to write a subroutine to manipulate elements of a list. A hugely simplyfied version to illustrate the problem is

ss[x_]:=(x[[2]]=3);
a={0,0,0};
ss;
Print

which gives me a setps error message, and outputs {0,0,0}.  What am I doing wrong?

Jim
POSTED BY: Jim Simons
4 Replies
You're trying to write the equivalent of a mutator method: http://en.wikipedia.org/wiki/Mutator_method

The alternative to a mutator is a function, which takes in an argument and returns something. In this case, a function would take a list and return the same list but a new value as it's second part. That would be this for example f[lst_]:=ReplacePart[lst,newvalue,2]. You can change the value of a list by running lst = f.

In programming you often have the choice between a mutator method and a function. Without going into too much detail, a function is generally preferable (unless there's a good reason). In fact a lot of programming languages don't allow mutators.

You can write a mutator method in Mathematica. Here's an example of a function that increments it's input by one:

SetAttributes[f, HoldAll];f[x_] := (x = x + 1);

I've use HoldAll as an attribute to prevent x from evaluating into a number which would present Set (=) from working.
POSTED BY: Sean Clarke
Posted 10 years ago
Ah, thank you: HoldAll is what I need.  I had stumbled into it in my earlier search of a solution, but hadn't inderstood the description.
It seems to me that what it does, at least in this context, is to convert pass-by-value to pass-by-reference.
POSTED BY: Jim Simons
Hi,
I wonder if you meant to type ss(number) (These brackets should be square, but this editor erases them) which is what produced the "setps" error for me.  If so, the specific error happens because when ss[2] is called, it results in evaluating the first function x[[2]] = 3, resulting in 2[[2]] = 3 which is not syntactically correct. "Print" by itself will also not produce an output, it must have something fed to it as an argument. 

If you were wanting to just replace the second element of the list "a", it is easy to do as follows.
a = {0, 0, 0};
(* The list a is modified in the following peration. *)
a = ReplacePart[a, 2(* The element at position 2 *) -> "Replaced" (* Replace with this element *) ]

(* If you only wished to generate an output without modifying the original list a,
you might choose to just type in the RHS without a semi-colon, to get the answer, but a will remain unchanged *)
ReplacePart[a, 2(* The element at position 2 *) -> "Replaced" (* Replace with this element *) ]
POSTED BY: Isaac Abraham
Posted 10 years ago
Thanks.  Yes, I see my entry has been mangled, I meant to call ss with parameter a, ie ss\lbrack a \rbrack, and then Print \lbrack a \rbrack.  
I had also tried

x = ReplacePart \lbrack x, 2 -> 7 \rbrack

within the subroutine, and that produced a setraw eror message, and also output {0,0,0}.
POSTED BY: Jim Simons
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract