As technical folk, we sometimes hear about “how to do business with other cultures.” But what about “how to code with other cultures”?
How do you trust a code review from someone whose upbringing of never publicly correct someone else prevents them from providing important feedback on your code review? Or is it a matter of framing, as in “What happens when B is deleted?” versus “This will blow up on production when B is deleted”?
For Canadians, at least, it’s the former because that's the polite thing to say and nearly all Western, English media will tell you Canadians highly value politeness. But what if that statement isn’t considered… polite? What if politeness varies across cultures? What happens to code during a code review then?
Increasingly, companies are putting a great deal of effort into hiring for diversity, and especially diversity of thought. Most employees avoid day-to-day conflict and learn to work with people from different cultures. But code reviews are different. A code review is a process that invites critical feedback and conflict. Moreover, code reviews are almost always delivered in written form and thus devoid of any verbal cues.
To prevent a misunderstanding, it’s important for developers to understand how different cultures approach reviewing codes, and how diverse teams can establish healthier communication practices when giving and receiving feedback. When we understand each other’s context, the emphasis can shift from confrontation to collaboration, from perfection to excellence.
To Please or Not to Please?
Navigating cultural differences in communication has long been part of my life. I was born in India, and I went to elementary school in India. I then attended middle school in Dubai in the United Arab Emirates. I did high school in New Jersey, and I went to university in Ontario, Canada, where I currently live with my husband and three kids. My husband is Caucasian, a second generation white guy born and raised in an immigrant family. His grandparents are originally from Eastern Europe—Poland and Germany. They moved to Canada during the Second World War.
Not long after I moved to Canada, I was waiting at a bus stop when a lady approached and asked, “Excuse me, please—please, if you could please tell me the time please?” I spent more time dissecting the question then answering it.
Her question continues to remind me of how different cultures perceive and expect politeness. I was raised in a culture where a question littered with the word please would be considered insulting. Such mundane requests are usually expected to be as brief as “Time?” instead of sandwiched in “politeness.” But that day was eye-opening for me.
I started noticing how my coworkers would order coffee: beginning and ending their sentences with please and thank yous. I heard these words everywhere—getting off the bus, at the hairdresser, sitting in restaurants. EVERYWHERE!
I had no intention of being rude, so I quickly adapted my language to include these words. A few years later, I was driving with my husband and his Canadian-born cousin. By this time I had gotten used to adding please to my requests. I needed a stop, so I asked my husband to pull the car over. “Can we stop at Canadian Tire? Please.” His cousin, who I was close with, commented how my please seemed tacked on and not genuine.
I was blown away. That’s how I had been saying ALL my pleases!
It took another couple of years before my pleases and thank yous seemed genuine instead of tacked on. There is still a long way to go. While I will now say pleases and thank yous, it’s not something I expect from others. This matters when it comes to my tiny humans, my kids, who are supposed to say please and thank you to their Caucasian grandparents, aunts, uncles, and cousins… but not to their Indian grandparents, aunts, uncles, and cousins. It’s not easy. My own mother has called me out on thanking her and saying please countless times as she finds it insulting.
I can’t change my mother. I can’t change anyone, really—but this made me realize how we can be quick to dismiss someone as rude. We can be quick to ignore someone. Something that kids in North America hear from a young age is, “What's the magic word?” We’re liable to throw out someone’s entire message because of one bad part. I’ve been blessed with the grace of many people who haven’t chastised me for my “rude” or “ignorant” behavior. They don’t get stuck in nuances of how I’m communicating and instead focus on what I’m communicating. Folks typically assume positive intent in my communication.
From Positive Intent to Invalidation
Positive intent: when you assume that the other person means well.
Giving someone the benefit of the doubt, when done right, can spawn wonder and collaboration. But oftentimes, positive intent can be wielded as a weapon. A weapon to invalidate, a weapon to ignore impact.
Effective positive intent is when we assume positive intent, not assert positive intent. Positive intent isn’t something you tell someone else to do, it’s something that you do. So when I tell you that your code is horrible in front of all your coworkers, and you come back with “Hey, it was wrong of you to embarrass me,” I don't respond by saying “Assume positive intent.” Positive intent isn’t a way to dismiss the impact of our words; it helps us minimize the biases and assumptions we’re making.
Done correctly, I’ve found that positive intent helps me navigate the biases I’ve developed during my upbringing. My upbringing taught me that please and thank you are formal and insulting amongst friends and family. My partner’s upbringing taught him that please and thank you are polite and important irrespective of the relationship. Assuming positive intent means putting my partner’s constant please and thank yous in the context of his cultural upbringing and not assuming them as a passive-aggressive expression of marital frustration.
How We Give Feedback in Code Reviews
Of course, cultures differ on more things than just politeness, pleases, and thank yous. As code reviewers and code authors, one cultural difference we naturally bump into is how we give and receive feedback.
Although Americans have a reputation for their directness, they’re similar to Canadians in how they give negative feedback: usually sandwiched between nice comments. “Great work!” might be followed by “You should work on your politeness,” and then followed up with “But, all in all, great work!”
A German or Russian may view the Canadian way of giving feedback as patronizing. A Japanese person may be outright offended that they weren’t given an opportunity to save face.
Consider how the following exchange during a PR review at Shopify could be taken completely out of context.
permalink
action here?”Author: “
permalink
and / checkout
share the same callback, hence I decided to not include them. Let me know if you disagree.”Reviewer: “If we changed the callback for permalink, I would personally expect to see a failing test, but I’ll let you be the judge whether it’s worth it :shrug:”
The reviewer comments on how they expected a test. The remark contains the obligatory Canadian question mark so it doesn’t appear to be feedback of any kind. The author explains why they don’t have a test. The reviewer comments again on how they expected it.
The test didn’t get added.
The reviewer is being a little passive-aggressive—not really asserting themselves, not pushing for a direct answer either. The author is being a little defensive.
In the end, it’s our codebase that suffers. Consider the same conversation—more curious, opinionated, and explicit. It’s feedback.
permalink
action here?”Author:
permalink
and / checkout
share the same callback”Reviewer: “The redundancy would give us a failing test if we changed the callback for permalink, a separate test would be worthwhile here.”
The reviewer starts with curiosity. The author provides context without implying that this is going to be a debate. The reviewer then shares their expectations and context without trying to avoid conflict and ultimately, dismissing their own feedback. To be clear: there’s no guarantee that this conversation would yield a different outcome, the author may have a reason to disagree but the explicitness of the conversation removes the underlying clash of politeness.
How We Receive Feedback
Another issue we regularly deal with at work is confrontation. We’re developers. We have opinions about tabs and spaces. We’ll disagree on anything. But whether or not being confrontational is a positive or negative quality trait—that too, is cultural.
At my previous workplace, we often worked on client projects in very small teams of one to two people. Another coworker and I would get paired often, and we both had very strong opinions and fiercely debated them. So much so, that multiple people questioned whether we actually got along. I was having lunch with this coworker a few months ago and he commented on how he misses having someone to disagree with. Nowadays, he’s less confident about his decisions. Everyone on his team just agrees. By refusing to engage in conflict with your coworkers, you’re being unfair to them. You’re depriving them of the privilege to not only educate you, but to learn and to be confident in their own decisions.
Here’s another example of a PR review, even more out of context, that occurred among developers working on Shopify Core.
Reviewer: “It’s not ‘my use’, it’s just what most of the codebase is already doing. Feel free to do it differently, I don’t think anyone will force this opinion on you or necessarily stop you. But then don’t be surprised if your code explodes in production (or worse: doesn’t explode but cause much more subtle problems) :smile:”
The reviewer comments on usage of mocks in a test and encourages the developer to avoid them. The reason? The issue being fixed in this PR would’ve been caught had mocks not been used to begin with.
Now, irrespective of whether mocks are appropriate or not, the reviewer’s comment, “I also don’t want to fight” is concerning. While the author ended up making the requested changes, imagine how hesitant the reviewer would’ve been to make any further comments. Observe how the reviewer personalizes the feedback: “If your code explodes in production.” Not if this code, but your code—even after correcting “my use” to “codebase”!
The only folks who lose out in this exchange are our merchants.
I want to dig further into the “don't want to fight” comment and what that means. When the reviewer said “I don’t want to fight,” they automatically disarmed the person. In other words, they’re fighting words. And worse, an unwanted fight. But why don’t they want to fight? Why is it even a fight?!
In my experience, I’ve found that this sentiment is expressed when we’re aiming for perfection, which then makes any feedback unwelcome and a fight. Consider the same exchange if the author had expressed curiosity instead of exhaustion from having to make yet another change, and the reviewer focused on providing context without dramatizing:
Reviewer: <Provide context on why this exists>
The Perfect Code is Collaboration
You know that perfect pull request: You do all the due diligence, proofread your PR, tests all pass, go over it 10 times before you request review. You’re sure you’ve covered every single case. At this point, a review is basically a formality, not an actual review. The code is perfect.
When we aim for perfection, we’re focused on doing the thing right—a lot of that is about appearances. Do others think it’s done right? But when we aim for excellence instead, we’re focused on doing the right thing. We’re focused on the results. We’re focused on the task’s success. We welcome feedback, which is motivating when perfection is demotivating (“I don't want to fight”). If the process is a collaboration, there's no fight because everyone is in the same boat. On the same team. Perfection is a lonely journey, excellence is a team effort.
There’s a rite of passage within Shopify involving a new hire’s first PR. Folks are shocked at how much feedback they get—at the level of granularity, the bar for quality, and well, that folks don’t go soft on them because they are new.
This surprises me. Let me explain why.
My development background started when I worked as an apprentice of sorts. I worked on a small website, but we needed to hire someone externally as the work that needed to be done was beyond my area of expertise. We contracted a local developer named Ben. Ben was given a fixed task list to work on with a fixed dollar amount. As he worked, I looked at his code and well… learned. Then one day I asked him if I could work on one of his tasks—he’d get paid the same—he’ll be reviewing code, instead of writing it. Et voila.
My first code review set my expectations for reviews as something that… invited feedback. There’s an underlying thought of “This is what I think or know. Thoughts on improving?” This doesn’t mean that I don’t have strong opinions on my craft. I do. But this does mean that we have to be very open-minded and to see past the language to the message. Understand that we’re all here with shared goals. See past the politeness or lack thereof, and ask, as a reviewer or an author, “Why does she feel this way about this? Is this an oversight or intentional?” Having disagreements is a beautiful thing and makes you a better developer, not worse.
Take the time to question. Take the time to answer. Take the time to educate. Take the time to ask for education. We all become better because of it. Say “I don’t know what this does” way more.
As developers we value self-learning. That’s great. But realize that we learn best from each other. Google is great at answering questions. But even with auto complete, a search engine can’t tell us what questions to ask.
For example, in school I somehow ended up being the only one in a class of 20 doing C++ while everyone else did Java. Long story, but the TL;DR is my school was transitioning from C++ to Java. Comp Sci I was going to be taught in Java but Comp Sci II was in C++ for the previous cohort. I wanted to do both of them the same year, so I had to learn C++. My agreement with the teacher stipulated that I would learn C++ from a book and can’t expect to take too much of his time as he had the rest of the class to teach Java too. Fine. I learned from the book and continued onto the Comp Sci II. I was now in a class of folks who had learned C++ like me.
cout
.
That’s how I would read and talk about doing basic output. I would pronounce it cout
(like boot). The book hadn’t told me how to pronounce the word.
Not only did my peers quickly correct me to c-out
but introduced me to the joy of printf
, which the book hadn’t covered yet.
Collaboration is a wonderful thing and we’re all better with it.
What if we considered the act of reviewing or being invited to review a piece of code made you the owner or a major collaborator? What if PR of the month listed not just the author, but also the major reviewers who contributed to that PR?
There’s an attitude change when we acknowledge that reviewers are just as important as the original author. Ownership of the PR by reviewers and authors—and not just the codebase—brings the same standards, the curiosity, the creative mindset, the forgiveness that we have when we’re the author. Reviewing code naturally becomes our craft just as much writing code.
Swati Swoboda is a Development Manager at Shopify. She has been at Shopify for 4.5 years and currently leads the Shipping Platform team.
Wherever you are, your next journey starts here! If building systems from the ground up to solve real-world problems interests you, our Engineering blog has stories about other challenges we have encountered. Intrigued? Visit our Engineering career page to find out about our open positions and learn about Digital by Design.