Skip to content

Instantly share code, notes, and snippets.

@shibukawa
Last active September 29, 2018 16:55
Show Gist options
  • Save shibukawa/9c9eba1e68c3721f96b6f1456cfc4271 to your computer and use it in GitHub Desktop.
Save shibukawa/9c9eba1e68c3721f96b6f1456cfc4271 to your computer and use it in GitHub Desktop.
Feedback for generics/contract proposals

Abstract

I don't think this generics/contract proposals have enough advantages. I am against them.

Why Generics is needed

For a long period, many people have wanted generics for the following purposes:

  • Avoid type casting from interface{} (as this proposal mentioned).
  • Improve performance (like C++'s specization feature like this).
  • Meta programming via reflect or generating go code generation is harder than original go programming.

In other words, their needs are simple like the following:

  • Needs more static typing power with few code (avoiding type casting, avoiding meta programming)
  • More performance with simple API (but many code should be written inside it)

Disadvantage of Contract

Go already has structual subtyping (interface). Contract and interface shares similar functionality.

  • interface can describe only pointer of structual types and their methods
  • interface is usable for regular variable/argument definitions, type casting.
  • contract can describe not only structual types but also primitives, non-pointer types, fields
  • contract is not usable for regular variable/argument definitions, type casting, only for generics.

I think improving interface is more useful for generics, and easy to understand for me.

And contract has another disadvantage like Java. Go user can't implement original types like some primitives:

  • Numeric operators (+ - * /).
  • Indexing, function call ([] ())
  • etc

If I want to implement generic mathmatic algorithm for int, float, complex, math/big, vector, matrix and so on, we should implement new stuct to wrap primitive type.

type Integer struct {
   value int
}

func (i Integer) Add(x, y *Integer) *Integer {
    return &Integer{x.value + y.value}
}

calcAverage(Integer)(&Integer{10}, &Integer{20})
calcAverage(big.Int)(big.NewInt(10), big.NewInt(20))

This proposal are useful only for types they are in same category (primitives, stuructural types). If input types are structual types, interface is enough to use.

If go has operator overloading, it would be more useful.

Disadvantage of Generics

At first this proposal doesn't have feature of specialization like C++. So this doesn't improve performance so much (only you can save some interface{} casting cost). This proposal aims only for saving typing and getting static typing advantage.

But I already described in advance, it needs more typings to use generics. So using generics have very few advantage.

Other proposal

We discussed about the generics proposal in Japan. Some people want to use generics because meta programming is hard. Other reason is creating tool for go generate is difficult (I did it and I have same opinion). Generics has too big side-effect to solve these issues.

For the first issue, if there are any good AST helper libraries (that absorb the different between instance method handling and pointer's method like usual Go syntax helps), meta programming issue would be solved.

For the second issue, If there are any Go pre processors that support good macro system (like Scala, not-like C/C++) solve this issue too. If editor supports the syntax of the macro, it is the best for me.

Conclusion

In my opinion, only using generics without contract like Java's collection are resonable. The advantage is not big, but it would introduce too many complexity to Go2. I disagree about these proposal and I think simple Go syntax is attractive than generics/contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment