# Why does this function fail when a non-function version of the same code works?

This works:

dogs = {{"chow", "medium", "brown"}};
dogs = Append[dogs, {"poodle", "small", "white"}];
dogs//TableForm
chow   medium brown
poodle small  white


but this doesn't:

add[name_, fields_] := (name = Append[name, fields])
add[dogs, {"pug", "small", "tan"}]
Set::shape: Lists {{chow,medium,brown},{poodle,small,white}} and {{chow,medium,brown},{poodle,small,white},{pug,small,tan}} are not the same shape. >>


The problem is probably very obvious, but I don't see it.

-

You can't assign to an argument in a function (ie pass by reference) without using HoldFirst so you could fix your code like so:

SetAttributes[add, HoldFirst]
add[name_, fields_] := (name = Append[name, fields])

-
Thanks. HoldFirst is still a little confusing for me. I wouldn't have figured this out. I should probably search on HoldFirst in SE and get a better handle on it. –  George Wolfe Oct 26 '12 at 2:52
Yeah I hear you ... took me a long time to even start to wrap my head around this. I found this guide invaluable for these kind of issues mathprogramming-intro.org –  Gabriel Oct 26 '12 at 2:55
Smiles, is it just me that finds this scary? Isn't this exactly the type of bug propagating side effect that functional programming seeks to eliminate ? :) –  image_doctor Oct 26 '12 at 11:01
@image_doctor Leonid Shifrin comments (somewhere) that Mathematica really isn't a functional programming language, but is instead a replacement rules language that looks a lot like functional language. There seem to be a lot of examples of using HoldFirst to do this. –  George Wolfe Oct 26 '12 at 13:34

You might also look at this question: Pass function or formula as function parameter . The accepted answer helped me a lot with a similar problem. The basic issue is that "name" is evaluated when it is passed in.

-
My search fould 101 HoldFirst questions. I was just wondering where to start. Thanks. –  George Wolfe Oct 26 '12 at 3:04