R3-Alpha's FIND function had a whole slew of refinements:
/part -- Limits the search to a given length or position
length (number! series! pair!)
/only -- Treats a series value as only a single value
/case -- Characters are case-sensitive
/any -- Enables the * and ? wildcards ; !!! Note: this didn't work
/with -- Allows custom wildcards ; !!! neither did this
wild -- Specifies alternates for * and ? (string!)
/skip -- Treat the series as records of fixed size
size (integer!)
/last -- Backwards from end of series
/reverse -- Backwards from the current position
/tail -- Returns the end of the series
/match -- Performs comparison and returns the tail of the match
Whenever you see that many options on a function, a good question to ask is what happens when you combine them? There's a working philosophy that you shouldn't have refinements that can't be used together. Does it know how to FIND/SKIP/MATCH/REVERSE? with a SKIP of -7?
When you're trying to rewrite the code to support something like--say--arbitrary UTF-8 encoded strings, you have to pare down the combinatorics if you're going to hope things will work. To try and make a bit of headway on this problem, I defined FIND-LAST and FIND-REVERSE like this:
find-reverse: redescribe [
{Variant of FIND that uses a /SKIP of -1}
](
specialize 'find/skip [size: -1]
)
find-last: redescribe [
{Variant of FIND that uses a /SKIP of -1 and seeks the TAIL of a series}
](
adapt 'find-reverse [
if not any-series? series [
fail 'series "Can only use FIND-LAST on ANY-SERIES!"
]
series: tail of series ; can't use plain TAIL, there's a /TAIL
]
)
That knocks off two refinements, and it keeps you from specifying something like FIND-REVERSE with /SKIP of a positive number.
This may not be perfect, and suggestions are welcome. But the only way to make the implementation tractable (in a way that gives correct answers) is to formalize the definitions in this vein.