10 ms·
Maybe this is unfair, but it’d be great if the Go devs could just say “generics will work similarly to [C# / Java / Swift / D / whatever], except that we’ll add
by iainmerrick 7y ago
Maybe this is unfair, but it’d be great if the Go devs could just say “generics will work similarly to [C# / Java / Swift / D / whatever], except that we’ll address [problems] with [adjustments]”.
Rather than going through this whole rigmarole of resisting adding generics too early because all existing implementations are bad, then slowly reinventing the wheel from scratch, then finally ending up with something pretty similar to one of those other languages anyway.
It’s OK not to make something completely new and different. It’d be useful to explicitly say which language(s) you’re borrowing from because you can then more clearly call out the differences and explain the reasons for them.
- grumdan 7y ago> because all existing implementations are bad I'm also not sure why in OOP-land, generics are this crazy experimental weird feature, when in functional languages, people figured out how to implement parametric polymorphism (the original term for generics) in quite reasonable ways. I get that subtyping adds some complexity, but overall I don't understand why such a basic way to build abstractions is so controversial in (some) OOP languages. If anyone has some context on why this is more difficult to have in Java-like languages, I'd be curious to hear it.
- RivieraKid 7y ago> I'm also not sure why in OOP-land, generics are this crazy experimental weird feature It's not, it's an essential, basic feature.
- evmar 7y agoThat's a really great question! One other factor is that functional languages typically are theory first, implementation second, while non-functional languages tend to more often have the language features follow whatever the implementation admits. I know for Go they fretted a lot about how you'd efficiently compile generics, which is not something that comes up when you're designing System F or whatever. But I believe that subtyping has a massive impact on generics, particularly in OOP languages where people expect to use lots of subtypes. There are all of these new questions around not only bounded polymorphism but also variance and mutability and how inference works. Even TypeScript, which is following a lot of the design decisions already established by C# with the same person behind both, is still kinda just meandering around the design space and continuing to make changes to the semantics in new versions.
- iainmerrick 7y agoJust to be clear, I don’t think all existing implementations are bad, that was my (possibly unfair) caricature of the Go devs’ position.
- deleted 7y ago[deleted]
- pvg 7y agoI can't think of a popular OO language where they are considered a crazy experimental feature. One historical reason for a certain reticence early on was people were unhappy with C++ templates.
- baby 7y agoIt makes code unreadable. void lol<A, <B, C<D>>, E>()
- Negitivefrags 7y agoThat isn't even close to valid C++.
- username90 7y agoIt is a valid template specialization declaration if you add template<> in front, like this: template<> void lol<A, <B, C<D>>, E>()
- filleduchaos 7y agoPretty much all syntax is unreadable if you don't know the lingo. For example, try presenting the ubiquitous for (int i = 0; i < 10; i++) {} to ten random people without prior programming experience and see how many of them can correctly tell you what all that means. Similarly, { a, b in a > b } is probably not very clear to people who don't write Swift and perfectly lovely closure syntax to people who do. There's language syntax that's actually unreadable, for instance due to using names that obscure or otherwise don't clearly express what a construct is/does or using the same operator/keyword for too many different context-dependent purposes. I don't quite think the sheer presence of angle brackets makes code unreadable, any more than the sheer presence of curly braces or parentheses do.
- baby 7y agoYou’re missing my point. While other syntactic elements can be learned, generics can be abused to make the code unreadable.
- Const-me 7y ago> generics can be abused to make the code unreadable All features can be abused to make the code unreadable. E.g. all modern languages have regular expressions in their standard libraries, despite complex regular expressions are essentially write-only code.
- gizmo686 7y agoInheritance makes generics difficult. For instance, if A < B (B extends A), What is the relationship betwern Array[A] and Array[B]? If you are just reading the array, you would want Array[A] < Array[B]. If you are writing to the array, you would want Array[B]<Array[A]. If you are doing both, you want Array[A] to have no relation to Array[B]. This problem doesn't come up in ML style languages because they do not make use of inheritence.
- justinhj 7y agoIt comes up in Scala. The solution is to have notation to specify the variance of types.
- gchpaco 7y agoAnd said notation causes the generic type system to be Turing complete, as in the Java case.
- norswap 7y agoI think it is Gilad Bracha that said, when the decision was made to include only covariance in Dart, that variance flies in the face of programmer's intuition. He's right. It's easy to understand one level of variance: you can replace a return type by a subtype and a parameter type by a supertype. (I wouldn't be surprised that many programmer don't undestand this.) Two levels already requires some deep thinking (assuming definition-site variance: `List<Object>` or `List<String>` as a return type / parameter type, was is allowed to replace it? More than that? (`List<List<String>>`) Hahaha, good luck. And by the way, Java has notations to specify the variance of type, but only at the use-site, which is different from doing it at the definition site (both enable expressing things the other can't do... but you can actually have both, as I think is the case in Kotlin, though there are some limitations).
- clhodapp 7y agoI'm not really sure what you mean. Variance just changes what is and is not a subtype/supertype. If List is covariant then List<T> is a subtype of List<U> if T is a subtype of U. So then, by induction, List<List<T>> is a subtype of List<List<U>> if T is a subtype of U. I'm not sure what's hilariously hard to follow here...
- hajile 7y agoIf go ever showed people the awesomeness of StandardML or Ocaml/ReasonML (and their amazing type systems), I think the language would lose a lot of users.
- weberc2 7y agoThis is confusingly phrased. Do you mean "If Go people were ever shown ... ML"? I would totally drop Go for an ML language if any of them had a sane syntax, usable build tooling (including native, static compilation by default), and a (single) decent standard library. A super awesome type system is worthless without the basic requirements for scalable software development.
- hajile 7y agoIf StandardML had even a fraction of the money behind go, there would simply be no contest. Ocaml is billed as the pragmatic ML, but the syntax really sucks and nominally typed structs aren't nearly as good. They also have 3 competing standard libraries. Haskell is too ivory tower. Most devs simply can't be bothered. StandardML is that awesome middle. The language choices are pragmatic compared to haskell (mutable refs, side effects, and not lazy). The syntax is super simple and consistent (unlike ocaml). The concurrent ML extensions offer good multi-threading (still waiting on ocaml). The mlton compiler is very fast. There's only one standard library and it's decent. The big thing holding the language back is third-party libraries. If Google threw their millions at SML instead of go, SML really would be better in every way.
- ernst_klim 7y ago>nominally typed structs aren't nearly as good OCaml structs are structurally typed. > They also have 3 competing standard libraries. There is only one standard library, stdlib.
- rndmio 7y agoYou know what he meant, if you want functionality comparable to the Go stdlib you are going to have to choose between Core or Batteries, then for async do you choose Async or Lwt? And as said the build system (when you're used to Go) is poor. I like a lot of what OCaml offers, but there's a lot of friction.
- idnefju 7y agoad-hoc polymorphism is where it shines. Such as the typeclass in Haskell or modules in OCaml
- kragen 7y agoGolang doesn't have subtyping.
- shaded-enmity 7y agoWhat is your point? Serious question. If you tell me, for example, that Go generics are going to be like C# generics, then I have to be familiar with the full semantics of C# generics. Essentially you tell me that in order to understand X I have to understand Y first, that's not good. Consumers of your language are not, for the MOST part, PLT nerds.
- iainmerrick 7y agoI’d compare it to e.g. the work on async/await in Rust, where the discussion seems more directly “we like this feature that C# pioneered and JS has adopted, here’s how we plan to adapt it to make it work well with Rust.” Admittedly, the Rust async/await RFC and the Go contracts proposal both discuss prior art in sections towards the end, so they are actually similar in that respect. Maybe it’s really just a question of tone and messaging, and the particular discussions that tend to end up on HN.
- shaded-enmity 7y agoFair point, however I think that you're mistaking language design discussion in a closed group of PLT invested people, and a blog post targeted at general audience. Visiting https://rust-lang.github.io/async-book/ https://rust-lang.github.io/async-book/ I don't see any mentions of neither C# nor JS. The key difference here is the audience.
- steveklabnik 7y agoThe async book is in the process of being re-written; I wouldn't be surprised if a comparison to JS ends up in there, given that we have some significant differences and it really trips up a lot of people who come from JS.
- jayd16 7y ago>then I have to be familiar with the full semantics of C# generics Or you could research the very detailed discussion and documentation available on the topic of C# generics.
- owaislone 7y agoProbably not as much as you'd like but I think the detailed proposal does talk about borrowing from Ada.
- helper 7y agoIf you're just going to copy another language there really isn't much of a point in making a new language. Go is not java, or c# or rust. Part of the explicit goal stated by the go team is that generics must still feel like go. If you slapped java generics onto go it would not feel like go.
- kragen 7y ago> if the Go devs could just say “generics will work similarly to [C# / Java / Swift / D / whatever], except that we’ll address [problems] with [adjustments]”. This is basically how C++ was designed, and it turns out not to work very well; the [adjustments₁] for [feature₁] turn out to introduce not only unanticipated [problems₁] with [feature₁] itself but also new and previously unimagined [problems₂] with [feature₂]. So the Golang designers prefer to take a much more cautious approach than the Lumbergh approach you're suggesting. So far it seems to have worked out well — the language is not without its compromises, and it's substantially more complicated than it was at first, but it's a very reasonable compromise.
- iainmerrick 7y agoI don’t agree with your point, but I applaud your use of Unicode.
- kragen 7y agoWell, consider C++ inheritance combined with object nesting; you get slicing copies. Or constructors combined with static objects; you get the static initialization order fiasco. Or constness with template functions; you get two, four, or eight copies of each generic function in your source code according to which things are const. Or (compile-time) overloading with (run-time) overriding; you get C++’s weird “hiding” rule about the other overrides you didn't override. Or separate compilation with implicitly instantiated templates; you get geological build times as the compiler instantiates the same templates in every .C file and then throws away all but one of the identical instantiations at link time. (To be fair, this is far from the only reason C++ compiles slowly.) Overriding combined with type conversions through implicitly invoked constructors (and implicit referencing and implicit casting to const) gives you annoying bugs that are unnecessarily hard to figure out. Cleanup from exceptions via RAII combined with C’s unspecified argument evaluation order led to a situation where resource leaks during certain kinds of operations couldn't be avoided reliably, a bug in the language definition that wasn't noticed for several years, though I think it's fixed now. The grammar is undecidable because of the number of different things that have been added, which sounds like a hyperbolic joke but is actually literally true, and a significant obstacle to implementing something like gofmt for C++. The combination of template parameters using <> for parameters, the traditional longest-leftmost tokenization rule, and the >> operator for bitshifting made foo<bar<baz>> an unexpected syntactic pitfall, one that is now fixed. There wasn't an exception-safe version of the STL for a number of years, which isn't really an interaction between templates and exceptions —a non-template container had to deal with the same exception-safety problems— but it did mean that fit quite a while you could use the STL or exceptions but not both. This is far from the extent of the problem. The C++ FAQ consists largely of affirmations of the form, “Doing [reasonable thing 1] works, and [reasonable thing 2] works too, but if you do them both, you will die horribly for your immorality.” It's exaggerating about the death part but the surprising problems are quite real. I don't hate C++, and I think it's the best existing language for some problem spaces, but it's very much the poster boy for unexpected problems arising from interactions between features. As far as the keyboard goes, https://GitHub.com/kragen/xcompose https://GitHub.com/kragen/xcompose and http://canonical.org/~kragen/setting-up-keyboard http://canonical.org/~kragen/setting-up-keyboard are your friends.
- karmakaze 7y agoFor my own benefit, I agree with this. I just want a more usable language now. Something like ad-hoc structural typing as in TypeScript with aliases seems close. For the future of languages I appreciate the clean slate effort. Go has been about scoping out a use area sticking a leg there and coming up with something that works well there. At the same time I dont think there will be anything revolutionary, just something that seems simple and compact. I wish them great success and us a short wait.
- weberc2 7y agoIt seems like you’re objecting to the messaging (not referencing an existing language, which doesn’t work for people not familiar with the implementation of that language) and also that, at its inception, Go didn’t pick (randomly?) a language off of which to model its generic implementation. Am I misreading?
- jayd16 7y agoReferencing existing work is not an rare or fanciful concept. If you're not familiar with prior work that's referenced in a paper then you can research that prior work as well. If prior work has not been referenced or addressed its usually considered a flaw.
- dalksfjid 7y ago>objecting Reads more like suggesting to me. And, a helpful one.
- iainmerrick 7y agoWell, there doesn’t seem to be a lot of discussion of alternatives at all, so I can’t really see what design and implementation decisions are actually being made. Most likely I’m just looking in the wrong place, and those discussions are taking place elsewhere. I guess my complaint is that this talk, like all the other updates on their progress on generics, implies that Go generics exist in a vacuum, whereas in reality there’s a ton of prior art that could usefully be referenced. Edit to add: this particular talk is focused on syntax details. Those aren’t unimportant but they’re a small part of the whole picture. As I commented on the detailed Contracts proposal, the decision to add contracts rather than simply using interfaces (as in Java and C#) seems significant but isn’t explained.
- jerf 7y agoIt was beaten unto death in github repo issues, mailing list topics, and wiki pages soliciting real-world examples. This post is basically a conference talk transcript. More stuff is in: https://go.googlesource.com/proposal/+/4a54a00950b56dd0096482d0edae46969d7432a6/design/go2draft-contracts.md https://go.googlesource.com/proposal/+/4a54a00950b56dd009648... including several callouts to other languages. It didn't all hit HN, or perhaps more accurately, it probably did all hit HN but didn't all get upvoted because how many times does HN need to chew on it in a month?