MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

How to short-circuit match failure?

When defining a function as a sequence of rules (with SetDelayed),
I often want to have messages emitted if the arguments do not have
the proper form, and then *stop* trying any remaining rules, but
I don't know how to do the latter.

Here's a silly example:

foo::toolong = "List is too long";
foo::nolist = "First argument is not a list";
foo::nargs = "foo called with `1` argument(s); 2 expected";
foo[x_List /; Length[x] < 3, y_] := {#, y} & /@ x
foo[x_List, y_] /; Message[foo::toolong] = Null
foo[x_, y_] /; Message[foo::nolist] = Null
foo[x___] /; Message[foo::nargs, Length[{x}]] = Null

The function foo takes as its first argument a list with length no
greater than 2.  But see what happens when foo[{1, 2, 3}, 3] is

In[86]:= foo[{1, 2, 3}, 3]
During evaluation of In[86]:= foo::toolong: List is too long
During evaluation of In[86]:= foo::nolist: First argument is not a list
During evaluation of In[86]:= foo::nargs: foo called with 2 argument(s); 2 expected
Out[86]= foo[{1, 2, 3}, 3]

The result in Out[86] is as desired, but spurious messages were
emitted.  It's easy to see why.  During the evaluation of foo[{1,
2, 3}, 3], *all* the rules associated with foo are tried, even
though the third and fourth ones should not be.

I can prevent this from happening by letting the second rule's
match succeed; e.g. by defining it like this:

foo[x_List, y_] := (Message[foo::toolong]; Null)

...but now evaluating foo[{1, 2, 3}, 3] no longer produces the right
final result (it produces Null, instead of foo[{1, 2, 3}, 3]).

How can I define the second rule for foo so that the third and
fourth ones are not tried, while the final value for foo[{1, 2,
3}, 3] remains as foo[{1, 2, 3}, 3]?



  • Prev by Date: Re: Mathematica 8: first impressions
  • Next by Date: Re: Defining constants causes integration to hang
  • Previous by thread: Creating rounded blobs in Mathematica 8
  • Next by thread: Re: How to short-circuit match failure?