| seems to be the canonical view among gophers that Go's paucity of features is about accessibility for programmers that don't understand them or find them cumbersome to work with Please keep in mind that there are differences at scale. What is "easy to work with" for 1 programmer over a month might not be so for 20 programmers over years. The argument can't be that paucity is good as a general condition, its that there are forms of abstraction and programming language features that Gophers find unhelpful or difficult to understand The argument is that simpler is better at scale. Airplanes can move freely in 3 dimensions, but airliners are constrained to fly in particular ways around busy airports and cross country. I also have a hard time believing that the ability to define parametric types and functions costs you anything. It's almost always self-evident when to use parametric types or functions, things that are "wrappers" or "collections" probably account for 80% of their use. I could see an argument for parametric collections and parametric sorting in Go. Not, however, for wrappers. The frustration of using Go is actually that I now have to consider the later as a possibility or trade off type safety by using unsafe casting. In your experience, what kind of "cost" has there been in unsafe casting to use collections? Even in environments like Smalltalk, where all use of collections amounts to "unsafe casting," I've rarely seen situations where a mistake of this type wasn't found trivially. Does your frustration come from having to abandon the "assured safety" the type system would give you, or does it come from an experience of the costs? |
For me, it's entirely about expressiveness. This:
where the type encodes that `reverse` is a function from a list of some type of elements to another list of the same type of elements, is more informative than this: where it's obvious that this list has elements of some type, yet it's not clear what the element type is, and it's not clear that the resulting list has elements of the same type as the input list.Beyond being able to express and communicate intent, there's the added benefit that the type system can statically check that the input elements are the same type as the resulting elements. There's also no worry about information loss associated with subsumption (the rule of subtyping that allows a value of a subclass to "become" a value of one of its superclasses, losing specificity in the process which may only be regained with a type cast (this is one reason I tend to favor row polymorphism as well -- no subsumption means no information loss and no need to cast)) because no subtyping is involved in this case of parametric polymorphism.