Earlier quoted context omitted.
I’ll flip this around… reusing comparison as angle brackets is the mistake. C++ ran into some issues too. I think Rust made the really smart move of putting :: before any type parameters for functions. Go made the good move of using square brackets for type parameters.
The problem can be traced back to ASCII/typewriters only including three sets of paired characters, plus inequality signs, which is not enough for programming languages. We really need five sets: grouping, arrays/indexing, records, type parameters, and compound statements. Curly braces {} are also overloaded in JS for records and compound statements, leading to x => {} and x => ({}) meaning different things. Square b…
In most languages, (grouping and compound statements) cannot syntactically appear in the same place as (indexing, records, type parameters, function calls). So we are immediately down to four.
Rust takes the approach that you use :: before type parameters, so they are easily distinguished from comparison operators at a syntactic level.
Go takes the approach that [] is just fine for type parameters—which seems pretty reasonable to me. In Go, there’s nothing that can be both indexed *and* take a type parameter.