7 ms·
If a language is not dynamically typed then it's cumbersome not to have generics, that's for sure. On the other hand what I really like about go is that they a
by discreteevent 12y ago
If a language is not dynamically typed then it's cumbersome not to have generics, that's for sure.
On the other hand what I really like about go is that they are the only popular recent language that pushes back against a lot of modern features and says: "It doesn't matter how clever those features are, overall simplicity and consistency matters more."
The point is that we really need this experiment. It's in everybody's interest that the go people push back and continue to keep the language minimal. In a few years time someone will say on the internet that unless you have features x, y, and z in a language you simply cannot be productive/concise/maintainable/performant/safe/not-a-blub. At that point it may be possible to point at some evidence and say "Well I noticed that those machine learning guys at myAppsTheGreatest.com wrote a large system in go". Then you can go study it and see if they really needed those features. You can also ask the developers who used it and hopefully some of them will also have experience in [insert crystalline functional language here] so you can get them to weigh up the pros and cons. Go is an experiment that is needed.
- bad_user 12y agoI personally like to think of simplicity as the opposite of entangled / intertwined, which is often at odds with easiness / familiarity. Rich Hickey has a very good presentation about it. I like doing that because then simple and easy are expressing 2 different things, both desirable but kind of orthogonal. > overall simplicity and consistency matters more Go took some good steps towards simplicity. OOP as present in languages such as Java is overrated and a primary reason for the complexity created. We could use some variations for this need for ad-hoc polymorphism that we have. Unfortunately Go doesn't go far enough by not addressing the need for type-classes or something similar. And the language doesn't have to end up with a type-system as sophisticated as Haskell if you want type-classes. Clojure has a similar mechanism called protocols and yet it doesn't have OOP in the traditional sense, Scala has implicit parameters solved at compile time that can be used to model type-classes and overall type-classes are a simplification because they cleanly separate data from behavior. Go also provides those channels as a more useful abstraction than plain threads. That's cool and all, but channels are not enough and a language should allow other people to evolve the language with even more abstractions for dealing with concurrency and parallelism, because there's no silver bullet. On top of the JVM people have built frameworks and libraries for actors, agents, csp, futures/promises, parallel collections, light-weight threads, STM, reactive programming / streams and most other things you can think of and the best a language can do is to allow evolution. One should not confuse a small set of features with simplicity. Java was also a language that refused in the beginning to have generics and then in version 5 it got an abomination - as in generics that don't specialize for primitives and that solve co/contra-variance by means of use-site variance and freaking wildcards, instead of the much saner declaration-site variance. This happened because backwards compatibility is important and an established language needs to be evolved by providing a sane migration path. Go is slowly losing its window in which it can make bold changes. Going back to your original point, a small set of features is bad if users cannot efficiently extend the language because the needed features aren't included. Having a small set of features is great, but it matters what those features are. I invite you to watch Guy Steele's "Growing a Language" presentation on this point, it's an astonishingly good presentation: https://www.youtube.com/watch?v=_ahvzDzKdB0 https://www.youtube.com/watch?v=_ahvzDzKdB0
- NateDad 12y agoExtending the language is exactly what the go authors and most experienced gophers don't want. I shouldn't have to learn your whole DSL / language extension to use or even read your code. Go intentionally disallows this so that everyone writing go is using the same language, rather than some subset, or god forbid superset, of the language.
- bad_user 12y agoWell, it's a wonder that you're speaking English then, since English is routinely extended by means of new words and metaphors. Look, you just used "DSL" and "code", words part of a domain specific language that regular folks do not understand, plus "subset" / "superset" which require basic knowledge of set theory. Besides, every time you create a new type or interface, you just extended your language with a noun or adjective and every time you come up with a function, you just created a verb. And I have to learn your nouns and your verbs to understand your code, even if you try explicit naming that don't really say anything (my personal favorite being variations on "processItems"). Go is not the first language to take this approach, it won't be last last either. Unfortunately people never learn and it feels like groundhog day, the movie.
- NateDad 12y agoThere's a difference between adding nouns and verbs, and changing the very structure of the language. If I say "I like to flargle my pofdin in a huffalop" you can still pick out the verb and the nouns, but if I say "#&_35( bar mdfsgh" you can't even tell if what I wrote is valid English.
- bad_user 12y agoWe aren't talking about changing the structure of the language, but about adding a feature to the language, generics, that would make it easier for people to build reusable libraries, especially libraries that treat functions (the verbs) as values that can be passed around, reused and still keep the static type safety of a language that is static. Thing is, if you want a language without generics, then you want a dynamic language, because a static language without generics is overkill for building reusable stuff. Go's structural typing is cool and all, that's ad-hoc polymorphism done tastefully, but we are talking about a different kind of polymorphism here with different use-cases. Watch that presentation, it's genius.
- tomp 12y ago> It doesn't matter how clever those features are, overall simplicity and consistency matters more. You mean, except the lack of simplicity when you have generic arrays and maps, and the lack of consistency when no other type can be generic? (Personally, I don't think generics are complicated, but people say that Go designers think so.)
- GhotiFish 12y agoboy I hear you there. That drives me completely insane about Go. They choose to have generics in these specific instances because if they didn't the language would be cumbersome. It's not enough.
- NateDad 12y agoIt's still a vastly simpler language than pretty much any other widely used language out there. Consistency is superseded by pragmatism in the language design.
- gnuvince 12y agoI always find this simplicity argument weak: SML is a simple language, simpler than Go (at least, in my opinion) and yet is more powerful with its Hindley-Milner type system and module system.
- tomp 12y ago"Power" is relative; it's very hard to put values with different types (where the set of types is not known in advance) into a list with SML, except by manually re-implementing the equivalent of Go's interfaces.
- wyager 12y ago> it's very hard to put values with different types (where the set of types is not known in advance) into a list with SML Probably because that's a terrible thing to do. If you want to keep a collection of things of different types, you should wrap them in a container type using ADTs.
- tomp 12y ago> you should wrap them in a container type using ADTs You can't; as I've said, the set of types is not known in advance. For example, you're building a GUI framework, where a widget has a list of children; you don't know what kinds of children the users of your library will make! The only way to solve this in a HM system is using closures (existential types), i.e. instead of adding a widget to the list of children, you can add it's .draw() method. This gets complicated the more method you need; you'll end up with a record of methods, i.e. an interface.
- wyager 12y agoThat's fair. I don't know how SML deals with this, but Haskell handles it with type classes and (in your UI example) existential data types. You don't know everything about the children's types, but you know enough to constrain them into being type safe. People sometimes do this safely in Go, but all too often they use interface{}.
- perturbation 12y agoIt's interesting that the pendulum has swung the other way in favoring readability over features. In many ways, Go seems to have something Pascalian lurking under its surface - WOCA with static compilation (and fast compile times), readability favored over terseness/expressiveness, and deliberately trying to limit what can be done (i.e., no pointer arithmetic) so that there is a 'sane subset' by default. I've played around with Go (worked through the Go Tour and implemented some trivial site scraping/JSON client stuff). It's an enjoyable, straightforward language, and it makes it very easy to get started, but I fear that it will be (like Pascal) eventually overtaken by something hairier. (Go : Rust(?) :: Pascal : C++)
- alkonaut 12y agoIn what way are any of these examples more readable than "proper" generics? A copy pasted solution with 3 different specializations is three times the code! The replace-"T"-solution is hardly any better in terms of readability than a modern (D/C#/Rust/Java) generic Collection<T> would be?
- kibwen 12y agoIt's a miscalibration to compare Rust to the complexity of C++. Rust is more complex than Go, absolutely and unequivocally, but that's because Go is hanging out with Lua waaaay out over on the simple side of the spectrum of programming language complexity. Given the enormity of its task, Rust is actually a rather minimal language itself (though there are definitely still a few features that I think could be made simpler). FWIW, I think it's misplaced to fear that Go will be "overtaken" by Rust. They both excel at different domains, and the systems software that you'd write in one is probably not the systems software that you'd write in the other.
- pjmlp 12y agoWhat you are forgetting is that the Pascal community also had Ada, Delphi, Modula-3, Active Oberon, Zonnon as languages in the Pascal family with some form of support for generics.
- deleted 12y ago[deleted]
- pron 12y agoI agree and I think Go has wholeheartedly adopted Java's philosophy stated[1] in 1997 by James Gosling -- "Java is a blue-collar language" -- and expounded in JavaOne 2005 in the following slide: * Reading is more important than writing - code should be a joy to read - the language should not hide what is happening - code should do what it seems to do * Simplicity matters - a clear semantic model greatly boosts readability - every "good" feature adds more "bad" weight - sometimes it is best to leave things out Obviously languages evolve with time. They need to change when their usage changes (for example, when they're used to build bigger and bigger programs) as well as when fashions shift, but when they do, they must do so carefully and conservatively. As a general rule, Java only adds new features not when they make something nicer, but only when they solve something that's really painful. I think this approach works especially well in large projects designed to last for years, made by large heterogenous groups of developers who might come and go over the lifetime of the project. One language that is somehow confounding in this respect is Clojure. It is minimalistic, but at the same time it's clever, so I'm not sure whether it belongs more in the minimalistic language category or the clever language category. [1]: http://dfjug.org/thefeelofjava.pdf http://dfjug.org/thefeelofjava.pdf
- masklinn 12y ago> It is minimalistic, but at the same time it's clever, so I'm not sure whether it belongs more in the minimalistic language category or the clever language category. Truly minimalistic languages can only be clever, because at one point you need to be able to build the language in itself, and that naturally opens things up to the user. Go isn't a minimalistic language, it's a simplistic one.
- pron 12y agoWell, Clojure isn't Forth and Go isn't BASIC, and they both have a similar number of built-in concepts, so I'm not sure your distinction is so clear-cut. But Clojure is certainly much more clever. As someone interested in large systems, I usually dislike cleverness in programming languages, but in Clojure the cleverness seems to be contained (though I'm not sure it's contained enough).
- dkarapetyan 12y agoThis is a non-argument on all fronts. I also noticed the other day that embedded developers for the betterment of assembly languages wrote a modern OS with just plain assembly and some Perl scripts to fill in the parts where assembly was not cutting it because it would have required too much copying and pasting.