Hacker News new | past | comments | ask | show | jobs | submit login

The syntactic choice of using square brackets instead of angle brackets for generics appears to be due to optimising for parsing. User clarity is decreased to allow for code optimisation IMHO.

From https://groups.google.com/g/golang-nuts/c/7t-Q2vt60J8 the following:

  Angle brackets require unbounded parser look-ahead or type information in certain situations (see the end of this e-mail for an example). This leaves us with parentheses and square brackets. Unadorned square brackets cause ambiguities in type declarations of arrays and slices, and to a lesser extent when parsing index expressions. Thus, early on in the design, we settled on parentheses as they seemed to provide a Go-like feel and appeared to have the fewest problems.

  As it turned out, to make parentheses work well and for backward-compatibility, we had to introduce the type keyword in type parameter lists. Eventually, we found additional parsing ambiguities in parameter lists, composite literals, and embedded types which required more parentheses to resolve them. Still, we decided to proceed with parentheses in order to focus on the bigger design issues.
Also https://archive.ph/tZJbB archive of original proposal https://go.googlesource.com/proposal/+/refs/heads/master/des... which suggested using normal parentheses (!) for reasons:

  Why not use the syntax F<T> like C++ and Java?

  When parsing code within a function, such as v := F<T>, at the point of seeing the < it's ambiguous whether we are seeing a type instantiation or an expression using the < operator. Resolving that requires effectively unbounded lookahead. In general we strive to keep the Go parser efficient.

  Why not use the syntax F[T]?

  When parsing a type declaration type A [T] int it's ambiguous whether this is a generic type defined (uselessly) as int or whether it is an array type with T elements. However, this could be addressed by requiring type A [type T] int for a generic type
Aside: it isn’t clear why not just make white space before the angle bracket significant - their examples of parsing problems are only if the code is not formatted “correctly” using gofmt. I think making the user type a space before greater-than would fix the parsing problem, and that seems like a reasonable compromise to reduce confusion for go vs most other languages. Square brackets usually mean indexing or arrays, and go breaks that pattern flummoxedly.

  F<T> versus f < t >
are syntactically different to read anyway ( whitespace is significant to pro grammers and writers for syntax ,for example).



How does using [] for generics decrease user clarity? They're both just grouping characters. If the argument is that [] is easy to confuse with indexing, then by the same token <> is also easy to confuse with comparison operators.

One could also argue that [] is the better choice precisely because it is similar to indexing a map - a generic type can be seen as a map of types to other types.


It certainly does for me. It ties into this quote:

> Why not use the syntax F<T> like C++ and Java?

A great number of us are used to seeing <> rather than [] for generics.

It would seem limitations in Go's parser outrank a popular norm.


If you look at some of the contortions that e.g. C# has to go through when evolving the language, due to numerous ambiguities between <> used for types and <> used in expressions, I think it's still a very sensible choice.


Square brackets in go have their own parsing issues (see my original comment). I haven’t found much discussion on how any parsing issues were resolved (presumably any issues needed resolution for backwards compatibility?).

As an outsider it appears to me that the choice for square brackets has been made mostly for stylistic non-technical reasons, but perhaps politically that would be difficult to rationalise to the user-base! Making whitespace significant before comparison/shift operators (matching the gofmt layout) surely solves the stated practical issue of lookahead parsing; although I admit many language geeks would say significant space characters were an ugly solution.

To agree with you: there is a really good discussion on the downsides of <> here —https://lobste.rs/s/fmcviy/language_designers_stop_using_for — certainly square brackets are used for generics in other languages (Scala, Python, Nim, Eiffel).

Regardless, the point is moot, given that the syntax is now concrete!

> then by the same token <> is also easy to confuse with comparison operators

Not really, given that comparison/shift operators are not used in types, whereas [] is used in types. Perhaps go-lang wanted to reserve angle brackets for constraint operators a la Scala <: et al. </wink>.

Disclaimer: I have little experience with generics or language design. I am just very curious if there is a divergence between the stated reasons for the design, versus any unstated reasons.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: