DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • How to Merge HTML Documents in Java
  • The Future of Java and AI: Coding in 2025
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • Using Python Libraries in Java

Trending

  • How to Build Real-Time BI Systems: Architecture, Code, and Best Practices
  • Designing a Java Connector for Software Integrations
  • Mastering Advanced Aggregations in Spark SQL
  • Infrastructure as Code (IaC) Beyond the Basics
  1. DZone
  2. Coding
  3. Java
  4. Go Doesn't Need Generics

Go Doesn't Need Generics

By 
Greg Hall user avatar
Greg Hall
·
Updated May. 22, 20 · Opinion
Likes (13)
Comment
Save
Tweet
Share
14.8K Views

Join the DZone community and get the full member experience.

Join For Free

Summary

A recent survey (https://blog.golang.org/survey2019-results) suggests that 79% of respondents felt that generics are a "critical" missing feature of Go.

I can only assume these programmers must:

  • Have a very different notion of critical than my own.
  • Work in very different problem domains.
  • Exaggerate.
  • Some combination of the above.

I won't attempt to figure out which applies. I will instead simply explain why I have never felt like Go needs generics. I'll begin by explaining what I have found using generics for years in Java, from versions 1.5 through 1.8.

I will say I'm not a religious programmer. I have no sentences about programming involving phrases like "have to", "never", "always", "you can't", etc. Getting 10 programmers to agree on practically anything is nigh impossible, and I have no interest in swaying anyone to my opinion. If someone feels generics are super important, it's a free country.

Java Generics

I began using Java personally when it was first released and began using it professionally at Java 1.5. When generics first arrived in Java 1.5, I did not sigh a breath of relief. I had primarily used generics in lists and maps, and did not find casting to be a burden. After all, you only have to cast when pulling objects out (return result) not when putting them in (parameters).

Technically, using raw lists and maps in Java allows adding random different types and probably getting ClassCastExceptions when reading values. In practice, most lists and maps are localized within a method - the structure is created inside a method and thrown away before it returns. In such localized uses, it is pretty obvious what type of data is supposed to be used, so casting values correctly is hardly challenging.

Who cares if you have to cast values when pulling them out? After all, Java's type erasure requires casting to be added to code that uses generic return results anyway. Just because you don't see it doesn't mean it isn't there.

I did encounter some problems with generics in Java, I'll just give a couple of examples.

Java Developers Actually Don't Understand More Than the Basics

Try asking 10 Java devs the following questions, and see how many they get right (chances are it will be zero):

  • How can I acquire Class<List<String>>?
  • What is the difference between List<Foo>, List<? super Foo>, and List<? extends Foo>?
  • Under what conditions are a generic type preserved at runtime, rather than lost to type erasure?
  • If a generic type is preserved at runtime, how can I determine if it is Map<String, Integer> via reflection?

In my experience, average developers don't understand these details, and simply don't care. They see it as irrelevant because they almost never write generic classes or methods of their own. Their usage of generics is generally limited to collections.

Generics Are Hard to Use in Libraries and Frameworks

Don't think so? Try writing one! Try handling the following:

  • Primitive and object types
  • Ensuring that primitives and their associated wrappers are handled interchangeably
  • Handling generic arrays, wildcards, lower bounds, upper bounds, and type variables
  • Analyzing generic signatures of fields, parameters and return types to ensure they follow some expected pattern
  • Translating objects between different generic types (eg translate a List<String> to List<[]String> by mapping each String to a one-element array)

What's the Real Benefit?

If devs on average only really use generics for collections, and writing libraries with it is hard, then doesn't it stand to reason that collections are their only significant use case? Perhaps the Go designers understood this, and applied it by making Go's slices and maps intrinsically generic through language syntax.

My coworkers, all of whom like me learned Go having come from a Java background, have never once made any mention of generics in the year and few months since we started using Go. Literally, the word has not escaped anyone's lips. I feel confident if I asked them what their care factor is, they would say that slices and maps are good enough, just as I would.

Strategies in Go

Since Go has no generics, at least for now, it's only sensible to find ways of dealing with it. I can think of a few simple ones.

The most obvious is to point out that we can pass anything for empty interface parameters, it is only for return types we have to cast. Using parameters whenever practical is the simplest solution.

In another article about the visitor design pattern, I showed a strategy of simply not declaring the one method in the pattern that would need to return different types in the declared interfaces. Instead, let each struct implementation declare the method to return whatever type is needed. Effectively, we have a design contract - every implementation would be expected to provide a certain method name with a similar signature, it just isn't formalized with an interface.

Suppose a struct has a small number of methods that return empty interface. Another struct could embed an instance of it, and re-declare the few methods in question to return a particular type. The implementation would merely call the embedded struct method and cast the type on behalf of the caller, like so:

See Go Playground

Go
 




x
23


 
1
package main
2
3
import "fmt"
4
5
type Foo struct {}
6
7
func (f Foo) Bar(i int) interface{} {
8
  return i
9
}
10
11
type FooAsInt struct {
12
  Foo
13
}
14
15
func (f FooAsInt) Bar(i int) int {
16
  return f.Foo.Bar(i).(int)
17
}
18
19
func main() {
20
  var i int = FooAsInt{}.Bar(5)
21
  fmt.Println(i)
22
}
23



Conclusion

I personally hope that Go never has generics, or if it does, the designers find some way to avoid the complexity and difficulties I have seen in both Java generics and C++ templates. There are no significant issues using plain old Go code, and it fits perfectly with my own preferences. Go is a breath of fresh air, particularly because the community seems to generally espouse simplicity over giant over-complicated frameworks. It is my sincere hope none of this ever changes in Go.

Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • How to Merge HTML Documents in Java
  • The Future of Java and AI: Coding in 2025
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • Using Python Libraries in Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!