I am teaching Go to a team of Perl developers. They have been writing Perl for years, some for a decade. They think in Perl. They have opinions shaped by Perl. The language is small enough to learn in a weekend. That’s not the hard part.
I did this once before, at the last company, with Node.js. The team there was PHP and Java, twenty-five fresh graduates who had never shipped Node in production. They learned. This time the people are different, and the people are what the method has to fit around.
Pick one person
The instinct is to train everyone. Workshops, a curriculum, bring the whole team to a baseline. I tried that with Node.js. It didn’t do much. People learn a language by building something real in it. A workshop gives them syntax and nothing to come back to.
You pick one person who wants to learn. Not the most experienced. Not the one assigned by a manager. Someone curious about the language for its own sake. At the Node.js company it was a junior who had been writing PHP for six months. She had the least to unlearn – which turned out to matter less than the fact that she was interested. We paired on an authentication middleware. A real feature, something that would ship. She typed. I sat next to her and explained the decisions, not the syntax. Why we return early instead of nesting. Why the error goes in the first argument. Why the callback gets a name.
The syntax she could look up later. The patterns she had to see someone make, on a real problem, in real time.
The middleware shipped. She knew enough to write the next piece alone. That is the only measure that counts – not whether she could explain closures, but whether she could build something that worked. She could. The next engineer learned from watching her. The third from watching the second.
Starting with Go
Here the first Go service is already running. Payment, a clean boundary - charge this, get a response, update the system. It went up alongside the Perl monolith a few months back. The next pieces are bigger: orders, wallet, services that carry state and entanglement. We need more people who can write Go.
I pick an engineer who has been writing Perl for seven years. He is curious about Go the way someone who has used the same tool for a long time is curious about a new one - skeptical, but interested enough to try. That is enough. We do not start with a tutorial. We start with a small endpoint in the payment service, something real, something he can finish today.
He types. I sit next to him. The Go he writes looks like Perl translated - long functions, deep nesting, logic that accumulates state as it runs. I do not tell him to flatten the nesting or break the function apart. I ask questions about the shape. “What happens when the gateway times out here?” “How does the caller know whether this succeeded?”
Each question points at a Go idiom without naming it. After the third one he starts reaching for the idiom before I ask. After two weeks his code is not idiomatic, but it works, it handles errors, and it is tested. The idioms come after the confidence. You cannot write idiomatic Go until you trust that the language will catch you when you do it right. That trust takes time.
Not everyone gets there. Some engineers write Perl in Go for months and the idioms never settle. The method works on people who want to learn. For the ones who were assigned, I do not have a method. I do not think there is one.
The review
Code review is where the teaching happens. Not because I leave comments about Go style – because the author has to explain the choices he made, and the act of explaining surfaces the patterns he brought from Perl without knowing he brought them.
He writes a function that takes a map, modifies it in place, and returns a boolean. In Perl that is conventional. In Go the function is doing two things and the caller cannot tell which one was the point. I do not flag the pattern in the review comments. I ask: “What does the caller do with the modified map?”
He looks at the call site. The caller does not use the map afterward. The modification was a side effect he wrote because Perl does that, not because the code needed it. The function drops six lines. He found the Go way by explaining the Perl way to someone who was listening.
The review is not about catching mistakes. It is about the author seeing his own patterns through someone else’s question. You cannot teach idiom by correcting syntax. The idiom has to be discovered, and the discovery has to be his.
The style guide comes later
At the Node.js company we published the style guide a year and a half after the first commit. By then the team had opinions. Everyone had hit a callback pyramid and climbed out of it. Everyone had lost an afternoon to a missing error check. The rules in the guide were not things I told them to do. They were things the team had already learned. The guide just wrote them down.
If I had written the guide before the first commit, it would have been my preferences. Nobody would have read it. Nobody would have had the scar tissue to understand why the rule mattered.
There is no Go style guide here yet. There will not be one for months. The team has not written enough Go to have opinions. When someone proposes a rule after being burned by the absence of it, the rule goes in. Until then the only rule is that the code ships and handles its errors.
A style guide that arrives before the team has earned the right to disagree with it is one person’s preferences wearing a different hat. A style guide that arrives after the team has the scars is a record of what they already know.
Unlearning
The difference between fresh graduates and experienced engineers is not about the language. It is about what has to come out before the new thing can go in.
Fresh graduates adopt patterns because they have no alternatives. When you have never shipped production code in any language, the patterns of the first one that takes you there feel like what programming is. They stick.
Experienced engineers have to unlearn before they can learn, and unlearning is harder. Every Perl pattern that Go rejects is a pattern that worked for them, in production, for years. You cannot tell someone their pattern is wrong. It is not wrong. It is wrong for Go, which is a narrower and more defensible claim. That distinction matters.
But unlearning goes deeper too. When a Perl developer writes idiomatic Go, it is not because he copied a pattern from a guide. It is because he understood why Go does it differently, measured against a language where it does not. That understanding is earned against a counter-example. It does not fade. It gets passed on.
