Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange behavior when using pattern match and HoldAll

15 views
Skip to first unread message

dnquark

unread,
Nov 7, 2009, 6:49:37 AM11/7/09
to
I am using HoldAll with a function that I would like to modify a list
passed to it, as described on
http://forums.wolfram.com/student-support/topics/21247
I wrote this:

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

Leonid Shifrin

unread,
Nov 8, 2009, 6:50:42 AM11/8/09
to
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

Albert Retey

unread,
Nov 8, 2009, 7:27:20 AM11/8/09
to
dnquark schrieb:

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

0 new messages