Go might soon include its most requested feature

About three years ago, I was working on a pull request approval manager for GitHub written in Go called Checks-Out. While building out the integration layer, I came across a situation where the straightforward approach in Go was overly repetitive. The ideal solution would have been to use generics, but they weren’t available.

However, I figured out that in many cases, you can use closures to pass values. I described my experience with this problem, and my solution in a blog post and a talk, both called Closures are the Generics of Go.

Things are about to change. The Go…


A deep dive into why the world depends on simple, reliable, well-understood technologies

collage of golang gopher wearing glasses
collage of golang gopher wearing glasses

I’ve been working as a professional software engineer for nearly 23 years, and I’ve been writing programs for about 38.

In that time, I’ve used a lot of languages. I love programming languages and learning about their new features and what changes they’ve made compared to the languages that came before them.

If you look at the past 10 years in programming languages, you’ll see lots of changes. C++, Java, Python, and JavaScript have gained new features, and new languages like Rust and Swift have changed rapidly since their introduction. …


Part of being a technology company is producing reliable technology at a rapid pace. At the same time, we cannot sacrifice code quality just to deliver slightly faster. One of the primary tools for ensuring code quality while maintaining a rapid release schedule is writing tests. Like any other skill, test writing has to be developed through practice and experience.

In this post, we are going to use a sample program to explore how code coverage and cyclomatic complexity calculations are useful for making sure that code is properly tested. We will learn how to use JaCoCo to get rapid…


Microservices are the starting point for your technical transformation, not the end.

Stone Soup is delicious if you add additional ingredients. Microservices are productive if you add additional techniques.
Stone Soup is delicious if you add additional ingredients. Microservices are productive if you add additional techniques.

Setting: Europe, During The Napoleonic Wars

Once upon a time, a soldier was returning from war. It was a long trip back home and on the way he came to a village. This village had been scarred by the war; everyone was huddled in their houses, unwilling to go out and help their neighbors. The soldier was hungry after walking all day and went to every house in the town, asking for some food. But no one would give him anything to eat.

When the soldier came to the last house, instead of asking for food he told them that he only needed a pot of…


4 Comparisons Between Go and Java

One thing that non-programmers often find surprising about programming is that different languages have different communities with different cultures. These cultures dictate things both large (how people decide what new features are added to a language) and small (tabs vs. spaces). They also pop up in interesting ways.

Recently, I was pulled into a discussion about the cost of reflection in Java vs. the cost in Go. I didn’t know the answer, so I wrote some benchmarks to see what the difference was. The most interesting part wasn’t the results, it was the design philosophy around benchmarking and what it…


A Satirical Take on Programming in Go

In my last blog post, I explained how to be an evil Go programmer. Evil comes in many forms, but in programming, evil consists of intentionally making code harder to understand and maintain. Evil programs ignore language idioms in favor of techniques that provide short-term benefits in exchange for long-term problems. As a quick review, the evil Go tricks we covered include:

  • Poorly named and organized packages.
  • Incorrectly organized interfaces.
  • Passing pointers to variables into functions to populate their values.
  • Using panics instead of errors.
  • Using init functions and blank imports to set up dependencies.
  • Loading configuration files using init…

A Satirical Take on Programming in Go

After decades of programming in Java, for the past several years I have been mostly working in Go. Now, working in Go is great, primarily because the code is so easy to follow. Java had simplified the C++ programming model by removing multiple inheritance, manual memory management, and operator overloading. Go does the same and continues this trend towards a simple, straightforward programming style by removing inheritance entirely, as well as function overloading. Straightforward code is readable code and readable code is maintainable code. And that’s great for my company and co-workers.

Like all cultures, software engineering has its share…


In my last blog post, we looked at Go’s reflection package and went through some quick demonstrations of the features it enables. What wasn’t clear is when these features would be useful. Everything we did with reflection could have been implemented without it — and it would have been more efficient and less verbose. But we also know that the Go team doesn’t like to include features for their own sake. So, what are the things that reflection enables?

Finding My Reflection

OK, so we can do all of these neat tricks with reflection, but how can I use them in my everyday…


What’s Reflection?

Most of the time, variables, types, and functions in Go are pretty straightforward. When you need a type, you define a type:

When you need a variable, you define a variable:

And when you need a function, you define a function:

But sometimes you want to work with variables at runtime using information that didn’t exist when the program was written. Maybe you’re trying to map data from a file or network request into a variable. Maybe you want to build a tool that works with different types. In those situations, you need to use reflection. Reflection…


Building a Futures Library with Channels, Goroutines, and Selects

Post 4 in a Series on Go

In previous blog posts, we’ve looked at how to use channels to build unbounded queues, pools, and manage multiple parallel requests. We’re able to do all these things with channels, and in these cases the abstraction made sense, but sometimes, we want to frame concurrency problems in a different way. For example, Node.js developers use the concept of futures (sometimes called promises) to organize callbacks and background tasks. How can we build futures in Go to achieve the same workflow?

If you aren’t familiar with futures, here’s the basic idea. They are a…

Jon Bodner

Distinguished Engineer at Capital One. Author of Learning Go. Interested in programming languages, open source, and the future of software engineering.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store