1. Why is it illegal in Swift to write a substring expression using integers, i.e. string[1..<10]?
There is no simple Int-based subscripting for String because in Swift, by design, String is a Collection, and types conforming to Collection are required to make performance *guarantees* for many of their methods.
Subscripting, for *all* types conforming to Collection, must be constant-time — it should take about the same length of time to look up any element, and the lookup mustn't depend on the number of elements in the collection. String can't provide this guarantee for Int indexes without a lookup table (from Int indexes to character positions, basically), and that would dramatically increase the memory used, as well as slowing down operations that change a string's contents.
There is currently a proposal that will allow Int-offset-based subscripting with a more verbose structure. This is a compromise to provide a better syntax, but which avoids implying random access. If this proposal is accepted (it probably will be), then your example would be written string[.start + 1 ..< .start + 10]. You can also offset relative to the end of the string, too.
2. Why does a substring operation return a Substring object instead of a String object?
Claude already gave you one of the answers (because substrings use the same String.Index values as the underlying String). The other reason is that it's too expensive to create a separate String for all substring operations, because that would require part of the underlying data to be copied. That would likely cause memory allocations as well as copying overhead. Substrings share the underlying string storage, so its trivially cheap to construct a Substring.
If you want to create a separate string, you can easily do that by writing String(someSubstring), but in many use cases you won't need to do that.
>>Apple saw fit to release something as a finished product but then make major breaking changes to it every year for four years in a row
I really wish people wouldn't say things like this. It's not really true. Apple never presented Swift as a "finished product", and told developers it would change. In most cases, the year-by-year changes were accompanied by converters that updated your code for you.
It is true that for several years in a row (until Swift 4), Apple made changes that required developers to spend time converting their code every year, and that was certainly painful, just not as dire as you suggest. FWIW, the bar for source-breaking changes in Swift is currently *very* high, in some cases to the detriment of the language's future.
>>I worked as a C and C++ developer for more than 20 years, and never in that time (or since, as far as I know) has anyone changed the languages in a way that breaks older code
C has been around since the 1970s, and *of course* the C standard has changed in source-breaking ways in the last 20 years. It hasn't changed *much*, because the churn and standardization in the language happened *more than* 20 years ago, when it was new. Kinda like Swift is now. C++ has been around since the late 1980s, and there was lot of change there too, also more than 20 years ago.