Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: ALL and ANY words

From: joel:neely:fedex at: 1-Feb-2003 10:09

Hi, Philippe, TMTOWTUT -- There's more than one way to use them... (with apologies to Perlophobes ;-) Philippe Oehler wrote:
> Ok.. I understand now.. With ALL, you can make a lots of stuff, > with conditions checks, and break opportunities, without using > long structures of IF.. it's cool >
ALL can play the role of a generalized AND ... all [a b c ... z] evaluates A and B and C and ... Z in order, but quits as soon as a FALSE or NONE value is encountered (in which case it returns NONE -- instead of FALSE, which is a bit counter-intuitive IMHO). <MILDSURPRISE> UNSET! is neither FALSE nor NONE, and therefore allows ALL to continue evaluation, as in
>> type? all [print 1 print true print false]
1 true false == unset! </MILDSURPRISE> Given that the expression if cond expr yields NONE if COND evaluates false, and otherwise the value of evaluating EXPR, ALL can be combined with IF in interesting ways:
>> a: 1 b: 2 c: 3
== 3
>> if all [
[ if a < b [print "a:b in order"] [ if b < c [print "b:c in order"] [ true [ ] [print "all in order"] a:b in order b:c in order all in order
>>
IOW, ALL can be used to sequence/control subordinate actions, with bailout conditions to interrupt/abort the sequence of actions. As for ANY, it can serve as a generalized OR, as in: any [a b c ... z] which quits as soon as a value that is neither FALSE nor NONE is encountered in evaluation (same MILDSURPRISE previously noted applies here as well). Therefore a common idiom is to use ANY to establish default values. var: any [expr0 expr1 ... defaultexpr] so that the first subexpression that yields a (non-FALSE, non-NONE) value will supply the value for VAR, and DEFAULTEXPR will supply the one if no others work: class: any [ if find seniors studentID ["senior"] if find juniors studentID ["junior"] if find sophomores studentID ["sophomore"] if find freshmen studentID ["freshman"] "unregistered" ] One (slightly contrived) example is to detect cases where variables have (intentionally) never been initialized, as in the infamous first time through a loop case. Suppose we want to determine whether a block of numbers is in ascending order. We could write this in a fairly boring way: catch [ use [old] [ old: block-o-nums/1 foreach new block-o-nums [ if new < old [throw false] old: new ] true ] ] or use ANY to handle the initialization issue for us: catch [ use [old] [ old: none foreach new block-o-nums [ if new < any [old new] [throw false] old: new ] true ] ] (I said it was contrived! ;=-) The point is that we can use ANY and ALL to do all sorts of interesting tricks. Having options is nice! -jn-