Predicates are IMNSHO an extremely clever notational trick, taking advantage of the inert TUPLE! forms that lead with BLANK!. It's already out there for a few functions, but now I'm going to add it to more...like ANY:
>> any .not.even? [2 4 6 7 10] == 7
This hinges on the idea that ANY can be confident you weren't trying to pass a value to act as the BLOCK! to be ANY'd, because .NOT.EVEN? is otherwise inert:
>> .not.even? == .not.even? ; inert (e.g. evaluated to itself) >> to block! .not.even? == [_ not even?] ; BLANK! is inert, and inert-headed TUPLE! are also inert >> 3.also.inert == 3.also.inert ; Same rule would apply for things like INTEGER!
So a skippable callsite parameter can pick it up, and run it on each value as the test (vs. the default test just for logical trueness).
But...What Does it Mean?
In my ANY example, the predicate is determining which values "pass" or "fail" consideration.
But notice we return the input to that process, not the result of the test. If we'd returned the result, we'd have gotten the result of the NOT EVEN? call, e.g. a LOGIC!
>> any .not.even? [2 4 6 7 10] == #[true]
That's not very useful in this case. Though we could have said you're supposed to pass in some kind of MATCH function, where it was both the test -and- the result.
>> any .match.tag! [1 "two" <three> #four] == <three> ; the result of `match tag! <three>`
But given that ANY is returning a single result derived from its contained items, is it really necessary to fold a potential transformation in with the act of picking? Can't you just apply the transformation after you've picked?
It seems that the best role of the predicate with ANY is to focus on picking, and have the understanding that its result will be either one of the items from the container or NULL.
But Wait--Generally Speaking, it's the REDUCED Item...
In the simple example I show, all the items in the ANY are inert. But they don't have to be.
This raises a question I've wondered about for a long time: What if you want to do an ANY operation on a block of stuff, but you don't want to reduce it?
In Ren-C all items have a quoted form, so you could MAP-EACH the block to a quoted version.
>> block: [1 + 2] >> q-block: map-each item block [quote item] == ['1 '+ '2] >> any .word? q-block == +
Seems a bit roundabout. But, at least it's possible.
But this might suggest an alternate axis for parameterizing ANY. What if instead of changing the test, you changed the evaluator, or took out the behavior of the evaluator altogether?
>> any .identity [1 + 2] == + ; or something like this
I Just Wanted To Introduce The Questions...
I don't know if we want to bend ANY all out of shape to get it to work just on inert data just as well as evaluated data. Maybe that's a job for another function?
But this is shaping up to be an important design issue, and it's new...so every operation is going to have to deal with it.
Something odd occurred to me about this idea of "before-or-after" results, realizing that even IF could have a predicate. That might seem useless, but conditionals pass the condition to the branch...so what if you could split your test out from that branch?
>> value: 1020 >> if even? value (x -> [print ["x is" x]]) x is #[true] ; IF received result of (EVEN? VALUE) as single argument >> if .even? value (x -> [print ["x is" x]]) x is 1020 ; IF got VALUE but ran EVEN? on it, then still had VALUE
Whether you think IF needs such a feature or not, the decision of whether the branch gets the result of the predicate or the value that was tested is something that has to be answered for things like CASE.
case/all .not.even? [ 4 [print "This won't print"] 7 [print "This will print"] 9 (x -> [print ["x is" x]]) ]
This seems pretty clear that you'd rather have the x be 9, and not #[true]
Anyway, I think this is all very cool...and I've managed to fiddle things around so that predicates are much faster. They no longer generate functions, they actually just splice the TUPLE! array directly into the evaluator feed. It's really neat stuff, so I hope people are looking forward to applying it.