> About using them as generics, how do you enforce constraints?
I'm really thinking about the case for numerical algorithms where the exact same code works for different types (say float32 and float64 in Go). It sucks to copy and paste hundreds of lines of code and it sucks to have a separate code generator write your file for you (essentially an external macro processor). Imagine something like the C preprocessor for Go, but without the well known flaws of the C preprocessor:
#define IMPLEMENT_FOOBAR(NAME, TYPE) \
void NAME(TYPE* ptr, long len) { \
hundred lines of implementation here \
}
IMPLEMENT_FOOBAR(foobar32, float32)
IMPLEMENT_FOOBAR(foobar64, float64)
That parametric polymorphic enough for a lot of use cases, and this could work with data structures too.As for constraints, you can pass function names as arguments too. For instance:
IMPLEMENT_SORT(sort_baz, baz, bazcompare)
Other proposed features in go, such as the "check" statement for error handling, are probably implementable as a nice macro if you had a good macro language. This means the core language wouldn't have to grow, and features like "check" could be imported from a library. Including features like this in a library means the core language isn't bound by backwards compatibility when a better idea comes along. Old code used the old library, new code uses the new one, and the language stays clean and compatible with both.