6 ms·
I see it the other way around, generics reduce complication and allow for code that's a lot more elegant and simple than without. It definitely adds complexity
by HideousKojima 5y ago
I see it the other way around, generics reduce complication and allow for code that's a lot more elegant and simple than without. It definitely adds complexity on the compiler side of things, but using them in C#, TypeScript, and Java has been only a plus. Unless you count that time I tried to do stuff with generic interfaces in Entity Framework Core, but that was EF Core's fault as opposed to generics's.
- tptacek 5y agoAs with everything else, sometimes this is true, sometimes it isn't. In languages with pervasive generics, figuring out how things work can mean following several extraneous layers of indirection as any opportunity to parameterize something is always taken. But writing the same stupid loop to delete something from a slice is also unclear and complicated. The point isn't that generics are bad, just that they should be used judiciously.
- gnoack 5y ago...and that time when people reinvented boolean expressions and their combinatorics under the disguise of Predicate<T> and Matcher<T>, making test errors hard to comprehend for very little additional benefit. etc etc There is also the problem that people don't generally have a good grasp on how to use type bounds[1] correctly... I believe Go avoids the worst of it through its simple type system, but still... this complicates a language significantly. [1] https://docs.oracle.com/javase/tutorial/java/generics/bounded.html https://docs.oracle.com/javase/tutorial/java/generics/bounde...
- pjmlp 5y agoStill better than messing with code generators and template language workarounds.
- CraigJPerry 5y ago>> generics reduce complication That goes against the definition of the word complication. To complicate something is to combine and intertwine it with other concerns. To fold them together is to complicate them. To generify a function is to complicate it with the ability to accept multiple types rather than just one. There are totally great use cases for generics but all the cases I’ve seen are in library code not in general application programming which is where most developers spend most of our time. But of course the shiny toy can be hard to resist and so generics are often overused and abused.
- stouset 5y agoAs a general rule, if you're referencing the dictionary definition of a word to make your point, you're just playing semantic games. You know what people also find complicated? Hundreds of lines code being repeated with superficial edits because of golang's lack of ability to abstract higher-level ideas. It's a stupid toy example, but for a very large number of people nums.take(20).select(&:odd).reduce(&:+) is less complicated than sum := 0 for i, v := range nums { if i > 20 { break; } if v % 2 == 1 { continue; } sum += v; } The former is less complicated for those people (including me) because it expresses high-level intent rather than low-level implementation. Multiplied over a large code-base, the ability to express intent adds up to an enormous saving in mental overhead rather quickly. You can always drill down and focus on implementation where it matters, but with golang there's almost zero ability to separate a program's detailed implementation from a high-level description of what you're actually trying to accomplish. The Ruby version of this is also less bug-prone (did you spot the bug in the go example?). And it's also easier to apply to new contexts: the former works automatically for infinite enumerations.
- cdelsolar 5y agoshould be == 0? I don't like the Ruby example myself.
- stouset 5y agoShould be >= 20. Whether or not you like the Ruby version is beside my point, which is that which one of those is "more complicated" is a matter of perspective. The Ruby one is almost strictly a wrapper around the golang one so it does add absolute complexity. But the golang one is relatively more complex, because the Ruby version uses higher-level equivalents, and those abstractions are good enough that I don't ever have to actually reason about what happens underneath the covers. Put another way, even the golang version is an abstraction around an absolutely massive amount of hardware and electrical engineering complexity that you virtually never have to think about. The absolute complexity of what happens when you compile and execute those instructions is extreme to the point that no single human or even room of humans collectively fully knows what's going on. And yet we manage just fine. Or, I love this example: admin_usernames = users.select(&:admin?).map(&:username) Versus adminUsernames := make([]string, len(users)) for i, user := range users { if user.isAdmin { userNames = append(userNames, user.Name) } } Again, spot the bug!