I'd say that's because df[start:stop] mimics python's builtin list slicing, which includes start but excludes end, so this dictates the behaviour of indexing without .loc. By contrast, df.loc[start:stop] is a label-based indexer, and labels can be anything (integers, strings, datetimes, categories, etc.), so it doesn't always make sense to exclude the right endpoint of the interval.
Edit: Corrected in the post. Thanks again!