Question about Optional[]
- To: mathgroup at smc.vnet.net
- Subject: [mg107419] Question about Optional[]
- From: David Bevan <david.bevan at pb.com>
- Date: Fri, 12 Feb 2010 04:41:39 -0500 (EST)
I'm using patterns for syntax checking of function arguments. Here's a trivial example of a function that takes two lists, consisting of 1 or 2 non-negative integers: In[] Clear[f1] f1[p:{_Integer,py:(_Integer?NonNegative):0},q:{_Integer,qy:(_Integer?NonNegative):0}]:=Tuples[{p,q}] f1[{1,2},{3,4}] f1[{1,-1},{0,0}] f1[{1,2},{3}] f1[{1},{3}] Out[] {{1,3},{1,4},{2,3},{2,4}} Out[] f1[{1,-1},{0,0}] Out[] {{1,3},{2,3}} Out[] {{1,3}} It is notable that missing 2nd elements of the lists are not actually defaulted to 0 in p and q (although accessing py and qy would return 0). Given that both arguments have the same 'type', what I really want to do is the following (avoiding unnecessary duplicate code), but it doesn't work: In[] Clear[f2] argType={_Integer,Optional[_Integer?NonNegative,0]}; f2[p:argType,q:argType]:=Tuples[{p,q}] General::optb: Optional object _Integer?NonNegative in Optional[_Integer?NonNegative,0] is not a single blank. >> General::optb: Optional object _Integer?NonNegative in Optional[_Integer?NonNegative,0] is not a single blank. >> It's not entirely clear what the problem is. perhaps there's actually a bug in Optional[]. The question: Is there some way of achieving what I want? Obviously the following won't work correctly: In[] Clear[f3] argType={_Integer,Optional[y:_Integer?NonNegative,0]}; f3[p:argType,q:argType]:=Tuples[{p,q}] f3[{1,2},{3,4}] f3[{1,2},{3,2}] f3[{1,2},{3}] f3[{1,0},{3}] f3[{1},{3}] Out[] f3[{1,2},{3,4}] Out[] {{1,3},{1,2},{2,3},{2,2}} Out[] f3[{1,2},{3}] Out[] {{1,3},{0,3}} Out[] {{1,3}} because it introduces a required match between the optional 2nd elements of the lists (because both are named with the symbol 'y'). Note that the optional 2nd elements of the lists are still not actually defaulted to 0 in p and q, although they are used for the matching. The real context of this is less trivial than the above example (and the desire for avoiding code duplication more obvious): iterType = _Integer|{_Integer?NonNegative}|{_Integer?NonNegative,_Integer?NonNegative,Optional[_Integer?(#1!=0&),1]}|{{___Integer?NonNegative}}|All|Infinity|{_Integer?NonNegative,Infinity,Optional[_Integer?Positive,1]}; Thanks. David %^>