Hacker News new | ask | show | jobs
by groovy2shoes 4530 days ago
The "code generation = code bloat" argument really fails when you consider that the code generated for a generic function is code that would be written by hand in the absence of generics.

Compare:

    map f [1, 2, 3]
    map g [1.0, 2.0, 3.0]
Versus:

    integer_map f [1, 2, 3]
    double_map  g [1.0, 2.0, 3.0]
In both cases, you wind up with specialized versions of map (one for Integers and one for Doubles). The benefit of the generic version is that the programmer must only implement map once, and the compiler handles specializing it for various types. Without generics, the programmer has to write the specialized version for every type he needs the function for. This creates more tedium for the programmer, and does not reduce bloat in any way.

Caveat lector: Though my examples above are written in Haskell, I don't have enough knowledge of GHC internals to know whether it performs specialization this way. Nonetheless, it could be a reasonable approach for Go.

2 comments

It seems like you disagree with Russ Cox.[1] Unfortunately, I'm not familiar enough with compilers to reconcile the disagreement. Any thoughts?

[1] - http://research.swtch.com/generic

In this regard, C++ templates suffer from two problems. First, C++ templates are far more general than just generic types (in fact, they're Turing complete). Second, and the cause of lots of redundancy, is that C++ has no module system. C++ has no module system, and instead relies on the linker to provide functionality that could reasonably be provided at compile time given a sufficient module system. I'd say that generics in Go could avoid both of these problems: first by being just generics, and second by leveraging the module system.

Yes, generics will increase compile times. I seriously doubt it will increase compile times by an integer multiple, and most people probably won't even notice.

I'm not entirely sure what's going on that is causing the instruction cache to be underutilized, but it seems to me that the only way to avoid it is to also avoid abstraction in general. As usual, there's a tradeoff between performance and maintainability -- that's nothing new. Pick the appropriate abstractions for your use case.

Russ Cox is wrong in this case because his sample consists of one language: C++. Go is not C++, so it's a mistake to assume it will suffer from the same problems.

To get an idea of how generics could be reasonably implemented, take the Clay programming language as an example: http://claylabs.com/clay/

You're assuming Go programmers will just write out the duplicate code rather than exploring alternatives. This doesn't seem to be what actually happens. Code written in Go isn't as concise as some languages, but it seems to have more to do with error-checking. I suspect we aren't seeing it because built-in types like slices and maps are already generic and people tend not to use fancier collections unless they're really needed.