Those two operations are not related to each other. It's more intuitive if you treat .indexOf() as .startOf(). Then "asdf"[0..x] is "as" for x=2, and ""[0..x] is "" for x=0.
If I were designing this, I'd want to treat this as an unsupported usage of "find".
If you're okay with using the same error code for (a) string not found and (b) erroneous usage, then returning -1 makes sense.
Since (b) is something that probably indicates a bug in the application code, I'd probably prefer that (b) triggers a different program flow. E.g., raising a C++ exception, failing an `assert`, etc.
but
"asdf"[0] is NOT "as".
so there can be no expectation that ""[0] is "".
Those two operations are not related to each other. It's more intuitive if you treat .indexOf() as .startOf(). Then "asdf"[0..x] is "as" for x=2, and ""[0..x] is "" for x=0.