Go Adopts Generics
Written by Mike James   
Wednesday, 17 February 2021

The most attractive thing about the youthful Go was that it was lean and left out all of the confusing things that other languages had. It has taken a long time, but finally Gophers have decided that generics are now part of the language.

Hard on the heels of the news that Python has adopted sophistication in the form of pattern matching, we now have the news that Go has finally settled on a way to incorporate generics. Right from the word go, pun intended and will be repeated, the major criticism of Go was that it lacked generics. Of course, many Go programmers didn't miss it and actively worked to make sure that it remained outside of the language. This was never going to happen as generics are so mainstream as to be part of the official dogma of modern languages.


It should be clear that in fact generics have nothing to do with the object idea. Generics are necessary only when you enforce strong typing and while strong typing may be part of most of the major languages, it isn't essential.  When combined with objects and the type hierarchies that object are usually taken to impose, things get complicated and you can easily lose sight of what is going on. Go on the other hand isn't particularly object-oriented and doesn't impose a type hierarchy, but it is strongly typed. What this means is that it is difficult to write an algorithm that works with a range of types.

When you write an algorithm in a typed language you have to say what types it works with and some algorithms are so general that they work with any type. So, to make it possible to write these general algorithms, you have to find a way of defeating the strong typing - either that you you have to write a program for each type even though the programs are largely the same.

There are a few things to say about generics that don't often get said, and if they do they cause trouble since strong typing and generics are deep beliefs. The first is that there aren't very many truly generic algorithms because most algorithms assume some properties and methods. For example, the most obvious generic algorithm is sorting and even here you have to assume that there is some function that can be used to compare entities.

The simplest solution to generics is to not enforce strong typing and simply rely on tools to check that the entities do have the properties needed for the algorithm - not a popular solution. The second best is to simply use the top of the object hierarchy - assuming that the language has an object hierarchy - and rely on the substitution principle to allow the algorithm to work with all other derived types. This often fails because few languages have a completely consistent object hierarchy - they usually have primitive types that exist outside.

If you don't want to use either of these approaches then generics is your only option - allow the programmer to specify the types used in an algorithm as parameters. That is, just as you use parameters to make a function or a method work with different variables of a specified type, you can use type parameters to specify the variables and their types.


It sounds easy, but there are all sorts of problems. This is where things can become really complicated: how do you restrict the types that a generic routine can use? What about composite objects such as containers? Should the type parameters be compiler-time or run-time entities and so on...

These and similar reasons are why it has taken so long to reach consensus - that and the fact that that a significant minority of Gophers didn't want the language expanded at all...

So what type of generics have they settled on? The simplest way of explaining this is to quote the summary in the announcment: 

  • Functions can have an additional type parameter list that uses square brackets but otherwise looks like an ordinary parameter list: func F[T any](p T) { ... }.
  • These type parameters can be used by the regular parameters and in the function body.
  • Types can also have a type parameter list: type MySlice[T any] []T.
  • Each type parameter has a type constraint, just as each ordinary parameter has a type: func F[T Constraint](p T) { ... }.
  • Type constraints are interface types.
  • The new predeclared name any is a type constraint that permits any type.
  • Interface types used as type constraints can have a list of predeclared types; only type arguments that match one of those types satisfy the constraint.
  • Generic functions may only use operations permitted by their type constraints.
  • Using a generic function or type requires passing type arguments.
  • Type inference permits omitting the type arguments of a function call in common cases.

I predict that any will be the most used type...


More Information

spec: add generic programming using type parameters

Related Articles

Python Adopts Pattern Matching - Kitchen Sink Next

Go Drops The Gopher - The End is in Sight

Bjarne Stroustrup Thinks He Has A Better Way To Do Generics

Covariance And Contravariance - A Simple Guide

Strong typing

Casting – the escape from strong typing

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on, Twitter, Facebook or Linkedin.



Do Specifications Lead To More Secure Code

A recent arXiv paper provides insights into whether program specification is a useful tool for security-related tasks. It also reveals that developers often fail to store passwords securely, despite c [ ... ]

Five Ways to Improve Your Personal Productivity as a Developer

Working remotely due to the global pandemic has disrupted our established working patterns. Here are five tips for techniques and tools to help maintain, and even improve, your programming productivit [ ... ]

More News





or email your comment to: comments@i-programmer.info


Last Updated ( Wednesday, 17 February 2021 )