It depends on language, library, and which substring function. And in some languages, like Bash IIRC, some functions and scripts handle differently `foo=""` (variable foo is set to empty string) and `foo=` (variable foo is not set).
As long as you consider cups of water and cups of milk be different objects (i.e. cups are not interchangeable, and you can't just throw out milk and fill it with water) it is a completely sensible statement.
For example, in Jewish religious families, there are often two sets of kitchen utensils - for meat products and for dairy/other products, since mixing those makes the food unfit for consumption by a religious person. In this situation, if you said "I have an empty meat pot" and somebody answered you "No, I need an empty milk pot, give me another one!" - it would make a total sense. Even though both pots are empty, they are not the same kind of pot for their users.
Similarly, if a string is a sequence of certain objects (characters, bytes, runes, graphemes, whatever you please) then empty sequence of such objects is not the same as an empty sequence of other objects - you could append a character to it, but you can't append a database connection to it, for example, and expect something sane to happen.
So yes, "empty cup of water" is exactly what it is, because in most programming languages, empty cups are not all alike. In some languages, there are sequence types that are agnostic towards their elements, and then an empty sequence of that kind wouldn't be a sequence of anything - it'd be just a separate entity. But strings rarely are implemented this way, for many practical reasons.
You entirely missed the point of the example. The point is not that you are supposed to embrace their beliefs. The point is that object that are all alike in one system can be very different in another, and if you assume they are all alike, you will misunderstand what is going on. Such as, if you assume that empty string is just "nothing", you will misunderstand how strings - and in general, typed sequences - work in most programming languages.
It's like a bad student that when the teacher says "assume the train departs from the station at 9 am", to formulate a math problem, objects "but the train actually departs from our station at 10am!". Way to miss the point!
So, but wait... Is the genitive "of water" functioning like an assertion? "All of the contents of the cup are water."
And wouldn't that assertion, in the case where the cup has no contents, be a vacuous truth?[0]
In other words, a cup of water, if it actually has water in it, cannot also be a cup of magma. But there's nothing stopping an cup with no contents at all being "of" both.
As long as your language includes an empty string concept, why not? Similarly, is an empty array a subarray of any array? And on the other end, can you have an empty number boolean?
But then if empty string are part of a string at what index do you find an empty string within a string you cannot dereference the space between letters