Language in Dev Culture

Published on by

Language in Dev Culture image

How we use language in development-centric circles is as important as the code we design and the sprints (development iterations) we plan. Especially as many workplaces have transitioned to full-remote (temporarily or permanently), it's more important than ever to reflect on how we communicate with each other. Just by rethinking how we phrase things in writing or over calls and video chat, we can make drastic productivity improvements.

First, let's look at the theory of why this matters. It's called "reciprocal determinism," coined by psychologist Albert Bandura in the 1960s. A very simplified version of reciprocal determinism can be described by saying your thoughts, your words, and your actions are an interdependent triad. That is, your thoughts influence your words which influence your actions which influence your thoughts; conversely your actions influence your words which influence your thoughts and so on. One of the driving mechanisms behind this is "cognitive dissonance". When what we say doesn't line up with what we do or what we think, we adjust some part of that triad (thoughts or actions in this case) so it lines up better in the future.

The good news is this gives us a spectacular hook into continuous improvement. If we aren't getting the results we want, and it's difficult to change our actions directly, we can tap into our language to influence it instead. Furthermore, we can do this not just for ourselves, but with others. Let's take a look at some scenarios and see how we can make some beneficial changes.

Responsibility and Ownership

Have you ever been on a team where something fell through the cracks? What happened to let that slide, and what happened afterward? If the fallout was The Blame Game, chances are pretty good that the responsibility, or the ownership of that task, was ambiguous.

There are a lot of reasons these things can be ambiguous. Sometimes, they just are. But, more often than not a few minor adjustments can help us avoid these situations. Take, for example, some of the following phrases: "I'm digging into it," "let's call that a spike ticket," "I'll get to that later," or "it's in progress." Context is everything here, but if the response to "how is [XYZ] going" is solely one of those phrases, that task won't be handled.

Why? Let's put this in the model of Reciprocal Determinism. The action we want to happen is for the task to be done, so a non-dissonant thought or conversation would involve more specific and descriptive language. For example: thinking of a bug, if instead of saying "I'm digging into it" we said "I'm looking for causes of [XYZ symptoms] and can let you know what I find," what do you think the outcome would be? Instead of something ambiguous, time indistinguishable, and frankly unactionable, we've transformed the task into clear actions we're taking ("looking for causes of...") with a discernible hook to allow others into the process ("...can let you know what I find"). For those on the other side of that statement, it's the difference between trying to hop a moving freight train vs. boarding a passenger train with assigned seating.

As a scrum master, this is what I strive for the daily scrum conversations to sound like. It's not just a status update where we list off the last ticket number we worked on, but a description of what you're actually doing to move the team closer to the goal. Even though it's just a quick reflection of what you did and where you're going, the more we leave the door open for others the more we can collaborate and help each other. In the previous example, just mentioning the symptoms of the bug you're looking into may remind someone else of a similar issue they encountered previously and it's very likely they have some insight that can help.

Furthermore, this revised statement creates clear actions for you to follow up. You've already established that you're investigating the cause of those symptoms and that you'll be following up with whomever after that. Whether or not that's on your task list, you'll experience a bit of discomfort (via cognitive dissonance) if you don't actually complete those tasks.

Accountability

Let's try another example. Say you're on a team with a particularly annoying or cumbersome problem that everyone seems to be stepping over or around. Assuming it's something that truly needs to be addressed, this is kind of a problem if nobody wants to take care of it. What have you noticed about the language in these situations?

In general, I've found it tends to be directionless. You'll probably hear a lot of "we've gotta do this", or even more nebulously "this needs to be done". These statements feel really safe, because there's no accountability. Saying "this needs to be done" leaves the door wide open for anyone to do it. Your Aunt Susan from Delaware might swoop in and take care of it, who knows?

Instead, let's be specific: "Pat, can you look into this for a while and jot down a few notes on how to handle it?" We've established something clear that Pat can do ("jot down a few notes...") with a semi-definite ending ("for a while"). Note here, we deferred the actual "doing" of the task in that request. Often, the truly annoying tasks are only annoying because they aren't (or can't be) well defined. By specifying a more concrete action, we can side-step that issue--- even if only in conversation. (Getting started on that task may be all it takes to actually figure it out!)

The same is true for our personal tasks. When asked how that annoying task is going, I can respond with "I'll be taking a look today at how we can best handle it, and will take some notes on ideal directions". With both of these statements, we've tapped into that dissonant nudge to look at it for a certain amount of time (which gives a better sense of "done"), and an expected result or outcome that we can show for our time.

Collaboration

Just like how we can nudge ourselves and others to take specific and actionable steps toward our goals, we can encourage others to join us as well. Social interactions are often centered around groupings, and we as humans love to categorize things (us vs them, you vs me, tasty vs nasty, dangerous vs. safe, etc.).

We can "add" people or groups to our group, just by including them in our language. Rather than "my work," it's "our work." Especially when it comes to issues, I encourage all my teams to consider an application problem to be "everyone's" problem. Jerry wrote that code? Who cares? It needs to be fixed! "Our application needs to be fixed" is a call to arms, whereas "Jerry's broken pile of crap took down the app" is a fight in the parking lot. Ok, maybe it's not that extreme, but when things are down it can certainly feel like it.

Just as we can band together to handle something, sometimes we need to do the opposite. To piggyback on the scenario in the previous section ("Accountability"), sometimes, it's better to exclude other groups or people from our language. For example, "I am going to fix this bug" is very actionable for me and it doesn't require anyone else. Not that we don't want help in this, but by excluding others from the action ("I" instead of "we"), it's clear that culpability rests with me.

One last note on collaboration, when other groups are distinct from yours and need to stay that way (e.g., developers vs. system administrators), we can still make them a part of our team by referring to them like we would extended family. "We'll need our Sysadmin friends to help with this one" resonates very differently from "we'll have to get the Sysadmins to do this." Without any context, I know I'd be more excited to hear the former than the latter.

Improvement

Up until now, we've primarily focused on influencing actions with our language. Let's switch gears a bit and look at influencing our thoughts. If you've ever used a mantra or self-affirmations, you know that words can be very powerful in shaping your thoughts. "Fake it 'til you make it" often rings true. In the development world, though, I often see the opposite happening.

What's your immediate thought when you hear "legacy code," for example? If you're like most, you probably cringed just reading the term. It can be complicated, convoluted, bug-filled, fragile, and every other horror we all have tales about. That feeling is what we want to get after and change. Imagine if working on legacy code felt more like walking into an old familiar restaurant instead of a haunted house? A lot of the difference is our mindset, and the way we talk about our apps can help.

This kind of "despair" phrasing extends to quite a few aspects of development life. Not just legacy code, but "crappy libraries" or "slow services" or "antiquated protocols", they all prime us to think poorly of the things we may not even be familiar with. Psychological priming is the phenomenon where the mere exposure of associated stimuli can influence your thoughts, words, and behaviors. In a famous study on priming, experimenters had participants solve crossword puzzles, then (unbeknownst to participants) timed how long it took them to exit the room afterward. One group unknowingly solved crossword puzzles with words like "geriatric," "elderly," and "retirement," and the other had random, unassociated words. The result? Those in the old-age priming group exiting the room more slowly than those in the control group. They had been "primed" to the notion of old age and its associations and inadvertently that affected their behavior.

Applying this back to our "legacy" or "bad" code, the same principle is in effect. You may be saying that it's all in the mindset, and you're exactly correct. Everyone will have their own approach and their own associations, but we can use our language to influence those. The goal in a lot of these situations is to shift that mindset from dismay, dismissal, or disgust, to improvement, amelioration, and for lack of a better word, enjoyment.

For example, say we're planning out a new feature that's trying to bridge the gap between some brand new feature or application, and the slightly aged code (see, I didn't call it legacy :wink: ) that currently runs in production. If we're looking to encourage the powers that be to spend time improving the legacy code for a smooth transition (and possibly better maintainability in the future), we can try priming feelings of needing "help" (rather than "despair"). Instead of "it'll be an absolute pain to connect this to that crusty old app," we can try "the older app will need a bit of TLC to support this." In the former, we've established that we're expecting a guaranteed unpleasant experience, that the previous code will be difficult to work with and generally that we're not very excited to do so. In the latter, regardless of how true the former is, we've noted that there is extra work needed ("a bit of TLC"), but most importantly that it is a step forward ("...to support this").

Takeaways

We've covered quite a bit so far, and as you made your way through this, I hope you were able to identify with at least a few of the examples. The most important piece of this whole puzzle is to realize that our words, our thoughts, and our actions are all interrelated. We can nudge any one of them by modifying the others, but here we focused mostly on our words. Personally, I've found the slight distance that remote work provides is an excellent opportunity to work on this. Through chat and email especially, you have myriad opportunities to refine what you say, before sending. Over time, and as we get better at being intentional with this communication, it will become second nature. The true goal of communication is to help your conversant understand your message, not to say things your conversant will understand--so please keep in mind that all of these tactics are personal and subjective. If I say to you "banana boing boing," and you definitely understand that I'm inviting you to get coffee next Tuesday at 2 p.m. at the cute little coffee place down the street, mission accomplished!

Here's a quick chart reviewing the phrases we looked at, and why we modified them:

Instead of... Try... Why?
"I'm digging into it" "I'm looking at the logs today to determine potential causes and will note what I find" Changes vague, ambiguous phrase into descriptive, actionable, and timely update.
"This needs to be done" "Sam, can you look at this for an hour or so and point us in the right direction?" Changes passive, unactionable, un-ownable request into specific action and expected outcome.
"Alex's crappy code broke the feature" "Our application is broken and needs to be fixed!" Removes the blame-game, and encourages the entire team to step up.
"Crappy old code" "Older code in need of help" Rephrases a negative sinkhole into a possibility for improvement.

1 https://en.wikipedia.org/wiki/Reciprocal_determinism

2 https://en.wikipedia.org/wiki/Cognitive_dissonance

3 https://en.wikipedia.org/wiki/Priming_(psychology)

4 https://psycnet.apa.org/record/1996-06400-003 It should be noted that a more recent replica of this study failed to produce the same results, there have been several other variants on this experiment (such as with priming "rudeness") that have affirmed the original results. The working theory is that individual differences in experiences with the elderly and their prior associations may affect the way primacy works in this case. Mindset and experience is powerfully influential here.

Zack Teska photo

Zack, Senior Developer at Kirschbaum, began his career as a web application developer almost 20 years ago when he started tinkering with PHP in his basement. Since then, his passion for learning and experimentation has driven his work with companies across several industries. He enjoys identifying business issues and discovering impactful, elegant solutions.

Having studied dance at St. Olaf College, Zack finds opportunities to incorporate wellness and the creative beauty of movement in both the digital and analogue worlds. Zack specializes in PHP, Laravel, VueJS, and Javascript, as well as Docker, Kubernetes, and CI/CD pipelines; and is always interested in learning something new.

Filed in:
Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Asymmetric Property Visibility in PHP 8.4 image

Asymmetric Property Visibility in PHP 8.4

Read article
Access Laravel Pulse Data as a JSON API image

Access Laravel Pulse Data as a JSON API

Read article
Laravel Forge adds Statamic Integration image

Laravel Forge adds Statamic Integration

Read article
Transform Data into Type-safe DTOs with this PHP Package image

Transform Data into Type-safe DTOs with this PHP Package

Read article
PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell image

PHPxWorld - The resurgence of PHP meet-ups with Chris Morrell

Read article
Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3 image

Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3

Read article