Clear[test]; Remove[test];
SetAttributes[test, HoldAll]
test[list_List, val_] := list[[2]] = val;
This doesn't work:
lst = {4, 5, 6};
test[lst, 99];
lst
gives {4,5,6}
However, test[list_, val_] := list[[2]] = val works.
Similarly,
Clear[foo]; Remove[foo];
SetAttributes[foo, HoldAll]
foo[list_List] := list[[2]];
lst={1,2,3}; foo[lst]
doesn't work.
Can someone explain why HoldAll changes the behavior of the function
depending on whether the argument pattern is specified as x_ or
x_List?..
Thanks,
--Leo
Hold-attributes do affect the pattern-matching. Have a look at
http://www.mathprogramming-intro.org/book/node408.html
where I specifically discuss this topic using an example similar to yours.
Regards,
Leonid
Because of the HoldAll attribute the argument is the symbol lst, not
it's value, the List {1,2,3}. This is why it doesn't match the pattern
_List but _Symbol and thus the function body is never executed. You can
check that this works:
Clear[test];
SetAttributes[test, HoldAll];
test[list_Symbol, val_] := list[[2]] = val;
If you want to test whether the value of the symbol is a list, you could
do something like this:
test[list_Symbol?(Head[#] == List &),val_]:= list[[2]]=val;
or:
test[list_Symbol /; Head[list] === List, val_] := list[[2]] = val;
hth,
albert