Re-purposing FIND/MATCH to be compatible with MATCH


#1

The historical /MATCH refinement to FIND is somewhat confusing. It basically requires the find to either occur specifically at the current position or not, and then returns the tail.

r3-alpha> find/match "abcd" "ab"
== "cd"

r3-alpha> find/match "abcd" "bc"
== none

Meanwhile, there is now a MATCH native which is used to do some type and typeset checking, not to mention running arbitrary functions as tests:

ren-c> match [integer! string!] "hello"
== "hello"

ren-c> match [integer! string!] <some-tag>
;-- null

ren-c> match :even? 10
== 10

ren-c> match :even? 13
;-- null

This makes one wonder if it might be more useful if /MATCH was the way of telling FIND not to use the argument as a literal thing to search for, but rather use as the same kind of rule that MATCH would use:

>> find/match [10 20 13 40] :odd?
== [13 40]

>> find/match [10 20 "hello" 40] [string! tag!]
== ["hello" 40]

This would help address an ambiguity that today’s FIND has, where if you pass it a datatype or typeset it very ambiguously will search either for the datatype, or for an instance of that datatype:

r3-alpha> find reduce [integer! string! tag!] string!
== [string! tag!]

r3-alpha> find reduce ["hello" integer! string! tag!] string!     
== ["hello" integer! string! tag!]

Putting the second behavior under /MATCH would clean that up, as well as bring more functionality to the table.

/MATCH sounds good, so what should the old behavior be called?

FIND has too many refinements as it is, some of which need to be done as specializations. The old behavior of FIND/MATCH is really just FIND/PART/TAIL, where the /PART limit only considers the very head to be a candidate.

You can actually make such a function by ADAPTting FIND such that it fills in the /PART to be exactly one past the input range. Then take the resulting function and specialize out the /PART refinement so it isn’t shown on the interface (e.g. doesn’t appear in HELP), and add in /TAIL as being used.

find-xxx: specialize (adapt 'find [
    part: true
    limit: next series
])[
    part: false
    tail: true
]

(Note: this should work today, except there’s a bug right now in Ren-C’s /PART I found as a result of trying this out. The specializing and adapting are fine, though!)

So really the question is just what you’d call FIND-XXX. FIND-AT ? FIND-START ?