Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Strategies for working with engineers that are too smart?
509 points by throwitawaaay on Jan 12, 2023 | hide | past | favorite | 474 comments
There are a couple of engineers on my current team that I can only describe as being a little too smart for their own good, and I'm struggling a bit with how to work with them. I've worked with this sort of engineer on previous teams as well, and they all share a few traits:

- They're brilliant, I mean very smart people (in an almost academic way?)

- They have a big appetite for adding complexity to systems

- They also have a big appetite for adding work to their own plates

- Their code has no consistent style

I work in embedded systems, so I'm generally writing C for resource-constrained systems. This sort of environment is rife with footguns, and I spend most of my time just trying to avoid those. A big part of that is keeping the things that my team controls as simple as possible, and while we are resource constrained, it's a balance. The tension comes when someone's more than happy to, for example, implement a complex caching scheme from scratch to save a few hundred bytes here, a handful of microwatts there. To me, adding that type of complexity for those sorts of performance improvements is missing the forest for the trees.

When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with. The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness. But the overall system becomes a little more brittle, and a little harder to reason about, two things that are much more difficult to measure than memory and power.

Here's an example: an engineer on my current team recently proposed adding a significant feature to a module I wrote to make something dynamic that's currently statically defined at compile time. I pointed out that we could just change a couple entries in a static table to accomplish his goals, and we were able to avoid the extra work. What was notable, though, was his immediate willingness to write that feature. Maybe I'm lazy, but I'd sit there and think of half a dozen other ways to do it before settling on changing the module itself. But because he's smart enough to easily reason about a complicated solution, and he's willing to take on the extra work, he stopped there without weighing it against the larger system.

Have you worked with engineers like this? Do you have any thoughts on how to work with them in a productive and friendly way?

--

One more example if you feel like reading more:

In a past role, I got into a debate about code style with the smartest person I've ever worked with. It boiled down to me advocating for more whitespace in his code and him arguing that adding whitespace made the code harder to read. It took a bit, but eventually I came to understand that he is so good at reading code that he just wants it all laid out in front of him as densely as possible. He can effectively run it in his head, as long as he can see it.

That was baffling to me, I walked away thinking that I must be pretty bad at reading code. I use a very consistent style with long variable and function names, I keep my solutions as simple as I can, and I use whitespace generously to provide visual cues about the code's structure. All of this is to minimize the amount of brainpower I needed to understand my code, so I can put that energy toward thinking about the problem itself.




As others have noted, part of the problem here is that the engineers in question are actually not yet smart enough. It usually takes substantial experience to identify simpler, more-maintainable ways to meet challenging performance goals. If you are not fortunate enough to have a veteran engineer who can lead the way in pushing back against unnecessary complexity, you'll want to try to grow your own.

This requires some luck, but there definitely are things you can do to help the process along. In particular, I recommend allowing some probably-unnecessary complexity -- I'd expect your engineers to innovate less and learn at a slower rate if you try too hard to stamp this out -- but be strategic in where you allow it. Software that is already load-bearing for your business should be subject to higher standards. Set an expectation that stable functionality becomes easier rather than harder to work with over time. When the backend has to become more complex to achieve performance goals, ask your engineers to do their best to encapsulate that complexity, and keep the higher-level interfaces simple.


I'd advocate that you make a bus factor [1] spreadsheet.

In the first column list every feature of your system - row by row - with a fairly identifiable description. List the current owner of the code supporting each feature next to the description

Then create columns with each engineers name on it. Then ask each engineer to color code each cell in their column based on their ability to support the feature.

Green - Understand the code and could support 24/7 pager duty on it

Yellow - Could probably grok the code after a month and then start supporting 24/7 pager duty on it

Red - Won't ever support that part of the code cuz its a mess

The presumption is that each engineer will be marking green for their features - so they will get 1 point. If an engineer signs up for another persons feature, they get 2 points for marking it green, 1 point for marking it yellow and 0 points for marking it red.

Tally up the points in each column and let the engineers compare themselves. Ideally each row will have at least 2 cells marked in green. Such a spreadsheet will definitely help guide the engineers to write more supportable code as if they don't it will be apparent that their rows are visibly red. It also gives the engineers a reason/reward for delving into Other People's Projects/code (I like to call it OPP).

Share the spreadsheet with the product management teams and engineering management - particularly as they are proposing new features as it can help show that their fancy new feature requests of the month are generating a high amount of bus factor.

[1] https://en.wikipedia.org/wiki/Bus_factor


This is a great exercise because it gets into the practicalities of engineering being a /team sport/ not a /solo sport/.

Many otherwise strong engineers who have developed strong muscles for solo engineering get into trouble when those "big muscles" aren't trained to the same degree the "stabilizer muscles" are. And so when they need to optimize for flexibility or applied "mental strength" they can do things that hurt themselves or those around them.

It's important to give them the tools to understand the additional constraints on the problems they are trying to solve, and moreover, to empower them to take responsibility for the struggles of the team, and not just their own struggles. That way, it's not a "me vs them" dynamic. Additionally and more critically, if they struggle with this exercise, it will make it very clear where they need more mentorship.

For what it's worth, having these strong "stabilizer" muscles alongside "big" muscles instead of just "big" muscles in and of themselves is, in my book, what separates a strong mid level engineer from a strong senior engineer and beyond.


>> That way, it's not a "me vs them" dynamic.

Yes - definitely helps in scenarios where an engineer starts talking directly to a product manager/non technical management and starts accepting feature requests and cranks them out with little thought about the long term supportability of their code by the rest of the team (and perhaps builds in a little extra job security intentionally or unintentionally via code obfuscation) and is reward by looking like a 10x engineer to the non-technical side of the company.

Rows of red next to their name will organically slow the engineer down and encourages less code that feels like "job security through obfuscation/abstraction" and long term will guide them toward soliciting more feedback from the team early on in the design cycle to ensure their code is grok-able enough to get green marks. Then they can truly by identified as a legit 10x'er.


> This is a great exercise because it gets into the practicalities of engineering being a /team sport/ not a /solo sport/.

The problem there is that, for many teams, there are 1 or 2 engineers holding water for a couple dozen people. the other ~20 people have no incentive to get better or take on more work because "Bob will just fix it". In this case, for Bob, it really is a solo sport.


That sounds like an interesting exercise. I would like to know about the 'red cell' scenario. Could you give examples of when someone would color a cell red?

My trouble is, a month is a super long time. So long as we are talking features, how messy does something have to be for someone to be unwilling to touch it (after a month)?

Could it make sense to simplify this and merge yellow and red together? Or change the definition of yellow to be 4 hours of code grokking (which would mean if I were paged, i could resolve the issue, but it'll take all night rather than knowing exactly where the problem is within 20 minutes)


Thanks! Definitely just made all of this spreadsheet up so feel free to modify to suit your team specifics.

As the generator of the spreadsheet I may have marked up the spreadsheet for myself as red for stuff I didn't understand but wanted/needed to understand - to reduce team bus factor - in order to show non-technical management what I wanted to spend time on to close the gaps. I also filled out some other team members' column and based on discussions would mark theirs as red.

I think the context of a month for yellow was "it would take a month to proactively grok the code (prior to any systems down/bug triage) as a 20% activity on top of other ongoing activities (stand-ups, your existing OKRs, support requests)" - so like 1 day a week dedicated to sitting down to grok Other People's Projects.

And now that you mention it - I might have said 2 weeks when I original shared the spreadsheet - so 16 hours to go from yellow->green.

Also important is to take snapshots periodically to encourage/reward improvements to making the spreadsheet red -> green.

A good work output to demonstrate a red->green transition is 1-2 small feature/bug fixes to a feature and/or a documentation update.


Well, i can think of at least one previous situation in which i'd not be confident in changing anything about it even after a month.

It happens when you're uncertain if what you're changing is going to break something that doesn't have explicit coverage or is mocked to a degree that the proposed changeset wouldn't cause the tests to fail.

I remember a company that had a spelling mistake in a central location of their code. When this spelling mistake was corrected, errors started to pop up days, weeks and months later forcing a revert of this correction several times.

So yeah, these things exist


> As others have noted, part of the problem here is that the engineers in question are actually not yet smart enough.

Yes, and more a matter of experience.

CS departments might not introduce this well, and the current Leetcode interview prep demands send mostly the wrong messages to students about what's important to learn about team software engineering.

One good way to learn this is to stay on a project long enough for the chickens to come home to roost. A better way is mentoring from people with battle scars. Or at least peer feedback from people who've heard not to climb the ladder to get the bananas (even if they don't have firsthand experience with why, nor an intuition for when the rules should be broken).


I don't think this is necessarily a sign of them not being smart. I mean it could be, but it could also not be.

What it is a sign of is that their incentive structures (their motivation) do not align 100% with those of the project. They might be more interested to learn and try new stuff, than to find the most maintainable, simple and elegant solution for example.

This does not make them less smart. And just because the participant's goals do not align with the project goals does not mean that this is bad. Such a project just needs someone who is aware of those individual goals and tries to defend the project against them while offering them sufficent opportunities to stay motivated.


I like the word “load bearing” here applied to software and business; it’s a good metaphor


"Don't remove Bob, he is a load bearing engineer"


You are absolutely correct. Being “smart” is not enough. The way I think about it is:

Competency = IQ * Experience

This is why you will often see less intelligent but more experienced developers outperform higher IQ less experienced developers. And why high IQ developers with 30 years of experience in many different software development areas are so valuable to a company/team.


don’t confuse smart with experienced

interviews do not currently optimize for hiring experienced people but rather people willing to grind leetcode


You don’t know that. It was my initial thought too, but further reading suggests possibility of good reasons for changes. OP may be missing something.


> As others have noted, part of the problem here is that the engineers in question are actually not yet smart enough.

That is highly subjective and purely a result of both perspective and bias. While you can point fingers to say that someone is not yet smart enough they are likely pointing a finger back at you and claiming the same.

The only solution for something like Dunning-Kruger is humility. The only solution to find the best solution (objectively) to any criteria is by comparing measurements. The actual problem is that almost nobody measures things, because the effort is too great. Instead most people will compensate for their lack of measures with a hearty dose of confidence.

There are people who sell confidence for a living, such as salesmen and pundits. That is highly appealing to people who lack the necessary critical nature to ask the right questions or apply the smallest amount of doubt.


Hard disagree. Perhaps "not smart enough" is too strong a statement but "not capable enough" is certainly correct. Spend enough time in this industry and you'll find plenty of folks who can work well in a vacuum but cannot actually be strong both independently and working in a group setting. The latter has a lot of concrete details attached to it which has nothing to do with either perspective or bias. Ironically, you're applying an accusation of "perspective and bias" with a very sloppy brush of perspective and bias.


> Spend enough time in this industry…

I have 20 years in this industry. It’s full of stupid people pointing fingers somewhere else. Any time this is pointed out developers play the special snowflake game and pretend that software is something special or unique, but it isn’t. Everything is measurable just like any other industry.


What have you accomplished in your 20 years in the industry, out of curiosity?


I have written the fastest network transmission implementation for Node.js and made the front page of HN (under a different account) for creating an original diff algorithm among various other things. While I was doing that I was also holding a part time job in middle management in an unrelated industry. This original software wasn’t written by whining and blaming people for my sadness.


Note that my advice, if followed, has the effect of giving the OP's engineers more space to develop efficient implementations than they would probably get if OP acts on their instincts.

This is not a coincidence. If you look at my own public work at e.g. https://github.com/chrchang/plink-ng/tree/master/2.0/ and https://github.com/grailbio/base/tree/master/simd , you can see that I play the role of the "not yet smart enough" engineer, not the manager.


People here are arguing the semantics of what you mean by “smart”, for no reason, because I know exactly the type of person you are talking about and they likely do as well. I call them “twitchy smart”, and I think they’re the worst to work with. In my experience, there’s no hope working with people like this because there is usually a strong case of stubbornness and unwillingness to see things from the other side. I have literally had to write code that automated cleaning up a person’s, who was like this, code because they were incapable of slowing down and doing it themselves.

My thoughts are that they need strong management to exert a lot of control and to come up with various ways of slowing them down and automated systems to gate check their code as much as possible (style guides, linting, static code analysis, tests and test coverage, auto-formatters, etc.). Otherwise, I think most people like this are just not worth having on a team because they aren’t interested in being part of a team and just want to solve problems they think are important. They will go off inventing all sorts of stuff, leaving a massive wake for the rest of the team. I also call them “wake makers”.


I call them complexifiers... because that's their habitual response to problems. I prefer to hire simplifiers (within reason).

Some complexifiers are not nearly as smart as they seem - they can often have tunnel vision due to their brilliance in specific domains, and miss the big picture. Which puts them in the "dumb and gets things done" quadrant: https://www.johndcook.com/blog/2010/12/27/dumb-and-gets-thin...


This is my experience - they are very often people who are so highly specialised in one thing that they lose the ability to talk to other people. Their egos are inflated (as no-one else understands them) they go around causing havoc.

I tended towards this but was - I guess - lucky to have had a manager who identified this and helped me grow.

My approach: the young ones need to fail. Hard. Then they'll learn.

The older ones who failed and reacted badly (it was everyone else's fault). I take them out of their comfort zone, tell them about my experiences and talk about the feeling of self-doubt when moving to different domains. Work with them to turn them into truly excellent team members (which they - in my experience - can be as they're usually driven, hard working and egotistical).


I've also had them read "Being Geek" and "Managing Humans" (as those books are what made it finally click for me).

Turns out the blog linked in the first post was written by the same person.


It is orders of magnitude harder to simplify things than it is to make them more complex. I think this skill comes with experience more than anything else.


There’s a big difference between:

- smart person, identifies a problem, wants to solve it with more complexity.

- normal person, doesn’t notice a problem (or doesn’t care), doesn’t attempt to address it, creates more incidental complexity.

The former is a complexifier. The latter is a typical dev.

Typical dev wants to do whatever is easiest. Complexifier goes out of their way to “fix” things.


> I call them complexifiers

Aka big brain developers

https://grugbrain.dev/


Short term complexity can also be long term simplicity. One can make an educated guess of what new requirements might emerge in next half a year and implement a more generic design that accommodates them from get go. If people are really smart, they may anticipate future needs not obvious to others, or they can of course overthink just because they can.


The real wisdom is knowing when to apply the complex generic pattern and when to just copy/paste/mutate an existing design. Also, enlightened coders will document 1) the choice and 2) the implementation so that future coders have an idea of why things are the way they are.


I don't agree that "there's no hope of working with people like this"; I've had a few "twitchy smart" people in my organizations in the past. This is valuable energy that can be usefully directed with competent management and technical leadership. But it requires a good understanding of the nuances at play, as you've noted, and a clear statement of the importance of the team's overall success, not their personal triumphs.


>> a clear statement of the importance of the team's overall success, not their personal triumphs

This doesn’t jive with my experience of devs i can see fitting with the OP’s description. Talk of team success just isn’t on their wavelength, you may as well talk about the weather. It’s a different value system, it values heroism, it values cleverness, it does not value useful business outcomes like maintainability or cost of ownership.

For keeping them on track, they can sometimes respond to automated controls better than to people telling them what to do. A linter in the CI pipeline will usually cause them to follow a style where another person could simply never convince them to make the same change. But everyone’s different and so even this is not guaranteed.


I really should have qualified that with “often”. Of course these are people and can be worked with, but without evolving, they’re worse than under-performers because they create so much stuff that everyone has to deal with.


I think my contention is that they can definitely evolve (at least based on personal anecdotes), but that they require a different management style. Sometimes that's okay with an organization, and sometimes it isn't.


I agree with this. Otherwise you end up in a dead company.


I was going to joke that it’s easy to tell who’s over 30 in this thread, but surprisingly the complexity farmers don’t seem to be correlated with age. It seems to be a learned habit that they just never drop. Indeed, they feel it’s a matter of professionalism not to drop it.

I agree with you that there’s not a lot of hope when working with such people. The best you can do is not to engage most of the time, then do some strategic social jujitsu when they’re proposing their astronaut designs in meetings.


It's not age. I have a uni mate the exact same age as me and we worked together and still talk about work.

He's the kind that would do his own oop framework in plain C (true story) while I would rather do the minimum necessary for things to work (well, if that includes UNAVOIDABLE complexity, so be it). It was like that when we were 25, it's the same 20 years later.


Well now I'm confused about which type I am. I consider myself a "simplifier", but writing your own OOP framework sounds fun I would have definitely chosen that route.


It sounds like fun, but would you choose to do that in a work setting?


Well I would surely do functions with a naming convention working on structs. Unless it's embedded development.

I wouldn't do a system of macros that allows me to "automatically" simulate inheritance etc though :)


I think both types can enjoy fun diversions. I think being a "simplifier" just means you can make a distinction between diversions and solutions.

For me, every additional moving part has a cost, and that cost needs to be amortized over sufficient use-cases. Sometimes writing your own OOP framework in C is just what the doctor ordered. Sometimes it isn't.


> The best you can do is not to engage most of the time, then do some strategic social jujitsu when they’re proposing their astronaut designs in meetings.

In that case, fire them. Seriously..

If you can't engage with someone, it does nobody any favors. Getting the team up to speed to agree on an approach can often take 10x longer than implementation. (Settimg up meetings, perhaps two days in a row three days from now, etc..) Set that pattern where it takes weeks to do design reviews, and the other person will be frustrated they spend all their time blocked trying to get the teams buy-in. So, they may go ahead and do stuff so that they can be unblocked.

Worse, if the rest of the team are just 9 to 5'ers, they have no incentive to dedicate so much time in a design review. They might not care.

How does a person consider the teams impact of a complex solution when it might not be obvious - by engaging. Perhaps the problem domain is actually very complex, the rest of the team is suffering from the "shit is simple" syndrome. Or maybe the inverse is happening. Either way, social jujitsu strikes me as very passive aggressive and not at all enabling for the _whole_ team. Sounds like it can easily devolve to a case of " we have a team of 10x'ers, but our process and team cohesion reduce efficiency by 95%"


> I call them “twitchy smart”,

I call them “cowboy developers“, and product owners and non tech manager sometime call them “10x developers” because they can delivery anything quickly.

In my experience, they are the worst people to work with.


Yep, I made a comment a while back about the difference between a true 10xer and a “cowboy coder” 10xer:

https://news.ycombinator.com/item?id=18462325


I wonder how the workers in the OP would react to being able to leave early if they finished a set amount of work.

"If we can get X,Y, and Z done you can take Friday off."

Maybe the appetite for adding complexity would decrease.

It wouldn't work for every instance of this problem but I'd be curious if anyone has tried it.


In my experience, a less complex but more thought-through solution often requires more time to implement. It's easy to just stick more layers onto a big ball of mud, but it takes excellence to change it such that these layers aren't necessary.


> Je n’ai fait celle-ci plus longue que parce que je n’ai pas eu le loisir de la faire plus courte. (I have made this letter longer than usual because I have not had time to make it shorter.)

~ Blaise Pascal, Lettres Provinciales (1657)


Or more generally, how does doing the simple low complexity thing benefit them? If you are a manager who wants your reports to just do the work that makes your job easier and you look good then you are in for a long hard road in most corporate environments.


This is a better formulation of what I was getting at.

If you have someone who can do the work, there is a lot to be gained from trying to fix the incentives because capable developers don't grow on trees.


It also sounds like a pretty good way to incentivize sloppiness, but I guess it might work if X,Y,Z are very clearly defined, including tests (and their quality), documentation (and its quality), and what not.


I have had similar experiences. Divas too busy showing of their computer science skills, not understanding that software engineering should be about managing complexity and keeping it low.


The problem is when you work for a company that values leetcode style quizzing interviews, then all you hear is how this new guy is such a genius and how he aced the interviews. Then you are stuck dealing with him in whatever SaaS crud app codebase you have to work in.


The rub is that not all problems are as simple as others try to make them out to be. Engineers who are able to vastly think through all of the nuance from business requirements and other systems that adds necessary complexity are by nature going to be seem like engineers who are attempting to add unnecessary complexity. A lot of the examples posted in this thread don't necessary sound like this case, but it's something I see on a near-daily basis at one of the BigCos -- engineers complaining that X is too complex when they're only looking at it through the Y lens and missing the other Z edges.

Even Senior Principals seem to over-ask "why are you building this new service when you could just work with the other team to modify theirs?" when in actuality working with that team would also mean working with 4 other teams who all have set roadmaps; it would result in a complete failure to launch. Even very smart people in high positions can very easily not grok such a situation.


The flip side of that is that not all problems are as complicated as they seem. "You Ain't Gonna Need It" is a thing for a reason.

Often the best solution from a business perspective is to ignore the complexity and throw the problem down the line. Sure, it won't scale to 1 billion users, but right now we are a startup trying to acquire our tenth customer. And there is often more than one way to skin a cat: why waste developer time trying to optimize something like CPU & memory usage when you can just spend a few dollars and throw an extra AWS instance at it?

Someone smart will solve the issue a few years down the lines when it actually becomes an problem.


We call them “clever”. Sure that was “clever” but we’re not looking to trick our coworkers and ourselves when reading the code later.


You had me until the last couple of sentences. Yes, the "twitchy smart" are actually just "immature clever" and it takes serious finesse to harness them to do something useful. The can be oh so frustrating to work with.

But the "wake makers"? You want to discard people who solve hard problems and invent things? Yes perhaps they have no place in _your_ team, but these types can be incredibly valuable to an organization, specifically because they are resistant to corporate middle management color-by-KPIs mediocrity.


The problem is that "wake makers" have a tendency to invent problems and then "solve" them. They will want to switch to a new framework because something about the old one bothers them. Heck, they'll even end up writing their own framework, in a language they themselves invented.

They see literally everything as a problem which can be solved by throwing as much complex code at it as you'll let them. Great for academia, terrible for business.


I totally agree with this comment. just such a person was the manager of the team I was on. and it wasn't really possible to argue. The only thing he understands from arguing is that he is right in the end. Imagine this happening even in the smallest of arguments.


100% agree. Do what you can with commit hooks (or however you enforce it. Some people argue these checks should only be done before merge), but ultimately the people you work with have to prioritize the team and the longevity/maintainability of the code base above their own desire to be clever or whatever it is they think they're doing. Oftentimes, as you hinted at, these types of people simply can't and won't change so getting rid of them is sometimes the only solution IMO.


Strong competent management does solve this, but it’s oh so rare.


I was one of them, and it took me burnt hard many times for me to change.


If you're ok with it, could you elaborate? Did you overreach technically, or did things come to a head with your management or teammates?


I never worked in tech. I started learning programming at a young age with BASIC, thinking I know everything, gotos are good, single letter variables are good etc. Even arguing with teachers when my working but spaghetti code got marked a low grade. Probably the reason why I didn’t end up in tech.


My background is similar to GP's. I would say that my first inkling that something was wrong was working alongside someone more egregious than me. I also spent half of my career supporting a product built by someone who sold his company to my employer, started another company writing add-ons for the product he'd just sold and sold that to my employer, then started another project and sold that to Google. Six years of cleaning up his messes was enough.

I really don't know of a way to learn that lesson other than the Hard Way. I definitely remember coworkers pushing back on my ideas and writing them off as boring and unambitious. Fortunately they had seniority over me, so most of my harebrained schemes never saw the light of day.


I've dealt with someone like this and it was a 3-year nightmare.

I'm curious what kind of automated cleanup you did that could make the situation better?


You could deal with it by automating stuff, but then they'll see your automation and say "that's so cool," and proceed to 15x the size of your automation code.


It is totally possible to use technology to solve some management problems.

However you can't solve all management problems with technology, and I'm not sure just automating the cleanup will fix it.


Linting, git commit hooks that enforce the linting. I'm guessing some static analysis tooling on the build server as well


If you haven’t read Stables and Volatiles[0] it’s a great place to start. It’s comforting to know that this is a common, structural management problem and not some one-off. Lots of engineering teams in lots of organizations have faced your challenge.

One of the things the blog post does really well is explain how a volatile can be valuable (even essential) in the lifecycle of a company. I personally tend to lean more toward volatile, so I can appreciate the tensions your colleagues are facing.

I have a few recommendations…

1. It’s very likely they don’t see the value of collaborative team work. You will all benefit from them coming to see the team as important. There’s no magic bullet here, but they’re still human and hopefully reasonable. Questions and conversation can help.

2. It’s possible they’re actually just insecure assholes. If so, work to remove them from the team ASAP. There’s no room for assholes.

3. If they are a volatile and they’re in a team which mostly benefits from stability, try to find a problem which is substantially challenging and useful to the team which you can hand them.

4. If there is no opportunity for that kind of challenging work, they might not be a good fit for the team long-term, and management owes them honesty about their fit.

Overall, I hope it works out for your team. Personality and work-style dynamics are tough but I have seen big changes on teams happen, and it’s possible for yours too!

[0] https://randsinrepose.com/archives/stables-and-volatiles/


If we are briefly going to play astrology-for-engineers then I guess I'm what would be called a "stable", but I kind of take issue with the dichotomy this post paints up in order to achieve what every tech writer seems to want to achieve these days: to be the person who Named Something.

This rigid definition into two different groups of people is pretty absurd if you just spend a minute thinking about it: in what other areas is it really reasonable to define human beings into personality binaries? The common response to this is always "well, it's a scale", like when people say they're a mixture of being introverted and extroverted -- another binary that does not stand up to scrutiny and seems to push the goalposts every time you poke at it, because most people do enjoy being alone occasionally, just like most people do not improve their mental health by avoiding others.

If someone identifies as halfway between a "stable" and a "volatile", that doesn't make them "a little bit of both", it makes the scale useless, because like a flatlander in 3D space it's obviously unaware of an entire dimension of human character and psychology. And yeah, of course these terms are created to "simplify" and "further discussion", but do we really need to put on a red or blue armband before having a discussion?

The picture painted here is one of the "risk takers" and the "risk avoiders", and while it tries its best to paint a fair picture it's pretty obvious it comes from a culturally American idealization of the Maverick, the risk-taking, 48-hour-working engineer who "gets it done(tm)" -- and I get it, that is valuable, and I've worked in companies filled with people who repeat phrases like "it's the way we've always done it", just as I've worked with people who got burned out re-factoring code, didn't care to document it and then quit, all in the name of this creative explosion the post seems to imply -- but if I can take anything from this post, it's not that these are natural laws of character that will repeat until the sun goes out, but rather that anyone solidly in the "stable" or "volatile" camp needs to work on their character progression to learn more from the other camp.

Nobody is born or raised into a role and then doomed to play it out for the rest of their life, we are very complex meat-bags that change over time, especially so in collaboration with others, so for anyone who feels like trying out the "Camp A" and "Camp B" advice when resolving conflicts in your workplace or when putting together managerial strategy, I'd implore you to maybe think again and tread a bit more carefully.


Thank you for this comment. I was reading the article and couldn’t agree more. Theres a place for hacking towards a goal theres a place for reliability. If you can only do one, then you are only half an engineer.

If success isn’t defined and these paths are left to individuals, then it seems like you have a problem with project scope and product management.


> Theres a place for hacking towards a goal theres a place for reliability.

Most engineers and managers believe this. Nobody agrees where that place is located.


If you can only do one, then you are only half an engineer

In a proper engineering discipline, the only place for hacking towards a goal is within the confines of the lab.


> hacking towards a goal theres a place for reliability

Yes, but in professional software engineering[1] where the roadmap exceeds 12 weeks, and the cost of a bug is non-zero, and you realize that in software engineering we do far more Reads than Writes to the code), then there are also dominant and dominated strategies[2]. Prototypes should be crafted from large blocks like low/no code solutions or generation... But once we have validation typically this is where good software architecture, and systems architecture come into play. Both the properties of the code that is written eg SOLID[3], and also the emergent properties of a collection of implementations.

All of this feeds into the total ROI of the engineering process. Quality issues lead to both churn[4], and slower roadmap (which means you lose out to competitors). People tend to think that "just make it work" is faster, but time and time again I've seen that only to be true in approximately the 6-12week time span. Hacky is fast until it needs to change, until someone else has to read it, until you realize there is a bug.

As well, it turns out that expertise in doing things well makes you faster the next time you go to do it well. I sometimes wonder if people doing things hacky/poorly is only faster because they've practiced it so many times? Often times well structured code is easier to read/write, fewer lines, easier to test, easier to morph into the next evolution. As we practice coding styles that give us these properties, we get faster at it.

So while yes there are tradeoffs, I don't think there are very many ways to take on lower quality implementation for time speed ups, both short and long run. Yes of course there are features you just don't need (your blog doesnt need to use CRDTs to update your post). And that tends to just having discipline in your Executive/Product team-- only ask for something if you have the research to make you think it will work, and the spine to stick it out to implementation. Engineers can also focus on stopping making bespoke software for prototypes. Pre GA mock ups should probably be using almost entirely light weight proxies for the product -- ui mock ups, generated code, SQLLite/PostgREST, low/no code solutions etc. to get strong data about usage patterns, user's needs etc.

[1]: "Software engineering is what happens to programming when you add time and other programmers." via https://research.swtch.com/vgo-eng .. I don't really care what you do in your spare time or on v0.0.0, but when we're on a journey as professionals to craft tools that 1000s to billions will rely on there's something more than just "it compiles, works on my machine"

[2]: https://martinfowler.com/articles/is-quality-worth-cost.html

[3]: https://simple.wikipedia.org/wiki/SOLID_(object-oriented_des...

[4]: (which means you cannot pay high CAC because you'll lose them before recouping cost)


You're right to be wary of pigeonholing people: thinking that Alice "isa volatile" and Bob "isa stable", and viewing all interactions with them through that lens, will be more harmful than helpful.

But there's value in recognizing and categorizing instances of behavior in these terms. It's hard to effect change over something you don't understand, and giving it a name is a useful step to understanding.


I dunno, man. I'm a (very) volatile person (in this dichotomy) myself and these days I'm aware of it. That wasn't always the case. But it really will piss me off if someone were to static my a$$ about something I really want to do. Now, this is not me saying I should obviously get to do it, this is me confessing to how I would feel about it.


I don’t think we have much disagreement here. My first two recommendations totally connect with needing to help people who are too firmly entrenched in one end of the stable-volatile spectrum.

The blog post itself describes a common evolution from volatile to stable through the course of an individual career, so I’m sure the author would agree that no person is predetermined as one or the other for life.

Lastly, I think ideas like volatile-stable have _explanatory_ value more than _predictive_ value. It can help defuse a tense situation to see that a team is falling into a common, age-old trap and then let the creativity of the whole team figure out how to solve it.

I don’t think we disagree as much as you seem to think we do. :)


Recommendations 2-4 aren’t great.

Instead, I’d recommend really working on recommendation #1 which is working on communication specifically…

1. Tighten the feedback loop for them. We all get the idea of using logs for engineering. People need the same for their performance. This means being willing to have difficult conversations and providing accountability.

2. Discuss in an open forum ways in which to solve the underlying problem and get commitment from the team as a whole to try new things like mob sessions or pair programming.

3. Most importantly, there has to be clear goal-setting. Meaning the team should be a part of that process to decide what they are attempting to accomplish and what their scope will be. This can be helpful for making sure no one is too far afield.

ONLY ONCE THE TEAM HAS DONE THE THINGS ABOVE

And if the engineers choose to not engage in good faith and work in the interest team would I consider termination or moving them to another team.


Thanks for this link. A solid quick read for anyone who has gone through stressful startup (or similar) work experiences.

I changed roles a bit ago and had to spend some time thinking through the battle scars situation that Rands calls out. It's definitely a bias to be aware of when moving on from a volatile, scar-inducing period to something new. I've repeatedly caught myself thinking don't want to do that again but sometimes doing that again is a phase of growth that still needs to occur for a new company or product. Not everything can be skipped because you're wiser this time around and I've had to work to navigate insight from having been there before vs. holding back the team due to baggage.

The new volatiles callout is great too as these teammates frequently need to experience the situations and see the cookie crumble before they can internalize and truly believe the tips others tell them.


The article on stables and volatiles was really great thank you for posting that. Its one of the first times I've seen my intuitions and feelings on problem solving described not only in a positive way, but also as a necessary yin-yang type relationship balancing the other side.


That’s a decent read, but I also take issue with the either/or mentality. Like there’s plenty of people whom the author would call "stables" that are frankly just slow, don't care, and/or don’t want to do much work, no matter how behind a project is. Similarly, there’s plenty of people who they call "volatiles" that aren't just cutting corners and hacking without caring about scale, but are just more comfortable with working and delivering incrementally.


> the value of collaborative team work.

It seems like there is not much evidence for this in the literature, and lots of evidence that extremely common practices around collaboration reduce productivity and creativity of orgs


The trouble is, I never became a stable after shipping 1.0 as the article predicted I would. But then maybe that's just because I was always pushed to do the next thing that required a volatile.


I can't directly speak to any particular work you're describing, but "smart" people don't usually add significant complexity and aren't hard to work with.

Their solutions tend to be obvious in hindsight and simple.

They work within the constraints they're given. They don't merely find one solution and push it through. They get satisfaction finding which fits best. If there's conflict, it's probably because they don't know how else to solve something.

It's true that sometimes there's only one solution, but that's rare and implies you're hitting bedrock fundamental stuff or have an over-constrained codebase that needs some refactoring. In those cases it would be apparent in other places too, not just when dealing with their code or opinions.


I've worked in academia doing a lot of simulation/modeling work with scientists that are experts in their field. Brilliant people but my experience is that scientists often generate the worst code you've ever seen. They are very smart, able to reason about extremely complex things, but they have often only learned just enough programming to solve the immediate problem they're working on and rarely need to maintain code past executing it once or twice to generate the data for their paper. So functions that are thousands of lines long with tons of mutable global state, loops nested halfway across the screen, no error handling, hacks like `eval`-ing strings because no one ever told them what a hashtable was, etc. The main difference from what OP has described is that despite those problems, the smart scientists are usually not hard to work with or stubborn about wanting to add unecessary complexity; learning "proper" software development was just never a focus for them.


The other thing I've run into in a similar context is perfectly performed manual work ("you didn't know about the merge function, so you manually typed the 15,000 rows of data into Excel?" And invariably, after coding it up, no errors found) or reimplementing things you could easily find in open source ("you didn't know about the merge function, so you found a textbook on relational algebra and implemented your own RDBMS in VB macros?" Again, a bug free toy database).

Some people are just smarter/faster/better than the rest of us, but they're no better at reading programming language documentation.


Honestly, the NIH should give grants for software engineers to come in and clean things up.


I think I understand what OP means. I work with some smart people who use code like

    val x: Pair<String, Pair<String, String>> 
instead of say

    data class Status(key: String, value: String)
    data class Item(name: String, status: Status)
    val x: Item
To the smart ones who can keep everything in their head, the first block of code is trivial and obvious and they don't even notice that it's hard for others to read and easy to make mistakes in.


It could also be inexperience.

If your experience is limited to academic projects, grinding leetcode, even competitive programming, you've done things where first one is nearly always optimal.

Once you are on a team optimizing for continued feature delivery over time, the cognitive load of picking up and understanding old code full of raw maps and strings starts to justify the overhead of a bit more semantic scaffolding in places.

IMO the necessary judgment has to be learned even by smart, academically talented people.


As someone getting close to 50, inexperience also seems to correlate with the ability to hold more in short term memory.


Agreed. Same age, same experience.

I'm also finding myself more allergic to unnecessary code complexity / non-standard designs, because they impede my ability to work with the code base.

It's still a little painful to no longer be the smartest person in the room, but I think it makes me a better champion for regular programmers who will need to touch the code.


I may not be the "smartest" in the room in terms of raw compute power of my brain, but as a result I'll write better code (more maintainable, easier for the next dev to understand). I want my code to be easy to follow. One of my personal rules I have through experience, is if I revisit a bit of code that I wrote a while ago, and I can't understand it easily, it's probably time to refactor it.


I've rarely worked in a team where the extra scaffolding was ever worth it. In fact chasing the scaffolding scattered through varied files through the filesystem was a lot trickier usually than fixing the actual bug I was trying to fix.


Design pattern spaghetti is absolutely a thing.

I feel like self-contained, self-describing, potentially self-validating data types like in the parent comment would tend to be complexity-reducing as long as they don't mix in control flow or deep deep inheritance hierarchies, though.


Which of these is better is a matter of distance and scope. If x is only used locally and within a screen or two of the declaration, adding a data structure screens or files away will make things harder to parse. If x is used in many places, passed around to many functions, or is otherwise far away from where it’s needed, it should be replaced with something that has better naming and more robust structure. If it’s the latter, you should rename it away from x as well, as the name of the variable is the first thing that should get documented as you increase distance. If you have a `Status` type already, then you should use that even if X is hyper-local.

Of note, the nesting here seems suspect, why not use a three item tuple or a flattened data class? In many cases I find where people start arguing about naming or abstraction, there’s a way to simplify things further so it’s readable for everyone and easier to use inline. I always look for those now when I’m reaching for “you should rename this” or “you should restructure this” kind of comments.


I think you're missing the forest for the trees here somewhat. What I believe GP to mean is that rather than use written out names and data structure layouts that make code easy to digest for others on the team, some folks choose code that makes their personal mental models easy to construct. This can be extremely valuable, but is also very bespoke and difficult to maintain.

I completely agree with your last point regardless: those kinds of arguments honestly held between well meaning team members are definitely a strong indicator that the implementation used is mismatching the use case at some level.


The actual smart ones would realize they are writing code for others rather than themselves and go with the latter.


That's a very useful lesson. Also recognizing that you won't remember the code the next time you see it. It only took me a couple instances of "what moron wrote this? ...oh, it was me" before I started including myself in the "dumb future people" I'm writing my code for.


I once worked with a guy with a rather good memory who wrote code like that and could maintain it for years. I was impressed with his ability until he hit his limit and made half a dozen of subtle bugs in one commit.


Geez never make a mistake in front of this guy or your years long reputation gets shredded.


He had been writing unmaintainable code for years and finally he experienced what it was like for everyone else. That's hardly a mistake.


Hmmm, I don't know about this example.

I'm kind of a certified idiot and the first one seems way more intuitive than the second one because it is succinct with much less abstraction. It's easier to "keep in my head" than the second one for me and, again, I cannot stress enough that I am not a clever man.


That's not about being smart or not.. But about brevity and a bit of experience.

I'd certainly recommend the first one, there's simply less stuff to parse, it's easier and quicker to read.

x is a pair with key of type string and value of pair with key of type string and value of type string.

The other one is overly verbose to read, it takes more effort to read and understand.. But it could have merit, for instance if you need to extract status into a variable of declared type later..


The first implementation is bad. It’s less stuff to type, but if you’re parsing it, you’re trying to understand it, and the second implementation makes the meaning clear while the first implementation is mostly meaningless. Code is written once but read many times. Be kind to your readers, which includes yourself in the future.


I strongly disagree.

My comment was from my immediate experience parsing what he wrote right there and then. The first one is easy to read and quick to understand, the second on is already like "oh god, now comes a bunch of stuff" and then "okay, he declares that, it's this.. fine" "Okay, he declared this thing and then the other thing is part of that, yeah" and finally "oh, okay he wanted a variable named X with a pair<string, pair<string,string>> geesh fuck just get to the point already!"

Like, seriously, it's like the analogy with the little kid explaining every little thing in excruciating detail, actually managing to make it sound like something is happening while nothing's happening.. Don't talk up this giant thing and tell me what you want to tell me.


> The first one is easy to read and quick to understand

No it's not. Let's look at it again:

    val x: Pair<String, Pair<String, String>> 
What does x represent? You don't know. Actually, there's no way for you to know what the person writing this code meant when they defined this variable. Sure, you know its structure, but how is it meant to be used in the context of the application?

This is one difference between junior and more experienced engineers. Junior engineers know what they meant when they wrote the code, but often forget to consider their teammates or future selves.


The difference is that self-documenting code is bad. Code isn't documentation for humans. Documentation is documentation for humans.

One comment right above this that gives a direct example of what x "is", is easier to understand. And then the structure of this line is also easier to understand more quickly than the second example.

Is this bad?

  // A tuple defining an item with a status. (item-name (status-key status-value))
  val x: Pair<String, Pair<String, String>>
But even knowing what x "is" either with documentation or with verbose "self-documenting code" it still doesn't answer your question of "how this code should be used in the context of the application"

Do we save x somewhere? Do we fetch something from somewhere else based on status-key? None of this is known. You get that from description, you get that from surrounding context. Except if we write all of our code like the second example then when we start reading the surrounding context it's going to be more painful.

We're hiding the structure with extra verbosity in the pursuit of not having to write documentation or use the best tool we have for communicating with other humans... natural language.


> val x: Pair<String, Pair<String, String>>

This just describes the structure. Structure without intent is useless.

Comments and out of code documentation both have the same problems : - Blindspots - Rot

That is not to say they are useless, but they are rarely if ever sufficient.

In the end, the most complete and trustworthy source of truth for the code is the code itself.

Help others by having your code describe your intent. Using appropriate variable name and using appropriate types _help_ to keep displayed intent in sync with reality.

Another point to consider is that for the same intent the structure may need to change, to evolve. Proper typing can insulate the code from those changes.


> Comments and out of code documentation both have the same problems : - Blindspots - Rot

This has nothing to do with the usefulness of comments (which is what i'm promoting). And no comments by themselves aren't sufficient for a system to do things. However, code by itself isn't sufficient to express intent. Code in isolation only serves to express a past *interpretation* of intent (not necessarily error free).

> In the end, the most complete and trustworthy source of truth for the code is the code itself.

For implementation I would agree. But not for intent.

Both versions of the code presented originally only give us the structure. The latter gives us some names. But neither gives us intent.

> Another point to consider is that for the same intent the structure may need to change, to evolve. Proper typing can insulate the code from those changes.

I think I can agree with this in some cases and not in others. Basically it boils down to if a new type is really warranted. My opinion is that new types are warranted if there is some functionality that is unique to that type. That's hard to say in this example because neither of the examples actually gave us intent or context. But if it's the case of we're only going to be doing "String" things and "Pair" things then I don't think it's warranted to invent new types to do the things the existing types already handle. It's extra abstraction and indirection.

As another commenter pointed out as well, a nitpick about the single letter variable name. It's something done in both of the original examples. It's bad in both but it's glaringly obvious in the shorter example. But changing the names here also really doesn't help us with the intent of the code. A good comment/description would.


>The difference is that self-documenting code is bad. Code isn't documentation for humans. Documentation is documentation for humans.

Surely you're joking? Code is meant to be read by humans. The comment above your single-letter variable doesn't count - just give it a proper name and use the type system.


The single letter variable is present in the second example for the thread that prompted my response. So the "single letter variable" argument is simply irrelevant. Regardless I wouldn't use a single letter variable name like this, so I do agree.

And no code is not meant to be read by humans. The generation of programming languages we have are simply the best we could come up with so far to approximate natural language. They're easier to read than previous languages, but they're not even close in expressive power to natural language.

Do we talk in code when discussing what a feature is or should do? Generally no. Do we use code to communicate in standups? Generally no. I don't see how it's joking to make the claim that humans understand natural language descriptions better and more readily than code descriptions.

As far as using the type system to document in this case. It just all depends on the context and the actual purpose of this code (which we were not given). My opinion is don't go out of your way to add more layers of abstraction just so you can have types with specific names. It's only warranted in my mind to do this when you need to add complex functionality specific to a type.

We very well might not need to do any of that. But unfortunately neither of the examples, even the self-documenting style one, explain the actual purpose of this code to us. Maybe if they had a bit more description for humans we could ponder on it further.

Also which would you rather change, a type system, or a comment?


Have you ever seen some sheet music, a schematic, or an equation and thought it would be more clearly expressed as a paragraph of English text? Those are meant to be read by humans too.

You don't have to abstract everything, but I like to use a type to add meaning. `String` and `Pair` are especially vague. Was it `UserName` or `UserId`? Was this the status code, or the message we want to display to the user? These are questions that can be answered (and mistakes that can be prevented!) by the type system. You can't get that with just a comment.


> Have you ever seen some sheet music, a schematic, or an equation and thought it would be more clearly expressed as a paragraph of English text? Those are meant to be read by humans too.

Every subject that invented each of these formats would disagree with you except for maybe sheet music (but we still use natural language heavily in music education). Do we learn how to interpret schematics, equations, and so on simply by interacting with them directly? It's possible but rare. These formats are consumed by humans, but they are definitely not native to us. To some degree written text isn't either, but it's much closer to speaking than any of these formats is.

I can understand your second point, but also it can be done in better ways than the two examples we were forced to start with. I'm not saying we do/don't have to abstract everything. But if we just want "names" or to know which arguments are what in a one line piece of code a comment is perfectly fine. Obviously as complexity grows we want more of what you are saying, but so far all we were dealing with is essentially a list of three values. And for that I just think two extra classes is too much. Maybe I'm arbitrarily being a minimalist, it's subjective.

If I had it my way java lambdas would be better and all of this would look so much nicer :)


It doesn't have to be a full-blown class, I'm happy with

    type UserName string
If I can't have that, I'll probably grumble and see how close Lombok can get me to that. It's gotta be close, right?

>These formats are consumed by humans, but they are definitely not native to us. To some degree written text isn't either, but it's much closer to speaking than any of these formats is.

Humans are wonderful things! We have so many means of expression outside of speaking. Have you ever heard those code audiobooks they tried to make for traveling engineers, or a python spelling bee? I'm sure there's something linguistic going on in written text that I don't fully understand.


What happens when you pass that variable around? Imagine looking at a function that takes "Pair<String, Pair<String, String>>". What the heck is it?

Well, since we decided to use opaque types, we now have to do a bunch of spelunking. We have to grep around for usages and trace that parameter alllll the way back to where it was defined in order to find that "useful" comment. Or, we could just use better types!


It was a freaking _EXAMPLE_ done in shorthand.


You don't have comments above your functions?


Don't need them when your types are well-documented. Whereas when you pick bad types, you have to do things like remember to copy-paste that comment explaining what it is, and keep them all up to date. How is that a better solution than just once taking the time to create a descriptive type?


Sorry, I don't copy paste and I don't create a bunch of types until code becomes complex enough to warrant it. And also writing comments is a more involved and important process than just copy pasting them around.


both snippets suffer from being stringly typed, that is not what is being discussed. Change the string types to something else mentally if it bothers you that much.

It was an example.


No way, the first one I understood the intent with a single pass, the second one had me jumping across all 3 lines to understand.

Succinctness is a virtue when used correctly.


Used to do a lot of Perl, which is a wonderful language for writing obfuscated code. If something is an advanced feature of the language and I felt the need to use it, I would ad a comment explaining what the code was doing.


It's a good idea to write _what_ something does, especially when the algorithm seems very "generic".

I'll a thousand times rather have

// Create users from id's

userList = theblackmagiconeliner;

Than a 20 line version of it where I'm left having to read through it to determine "oh, it made users from a list of id's" or even just.. having to read through it to find out if there's other stuff plugged in because "it could go there" or even just finding where it ends and actual work starts.

userList = userListFromUserIdList(userIds);

is also perfectly acceptable, but if it's only used once in that file, I'd prefer the blackmagiconeliner.. If it's only used once in the project, I'd also prefer that to having another file just for that function. Just do the work and get on with it.


Put the 20 line version in a properly named function, even if it's only used once. There are two reasons for this:

1. You're probably doing something else where you don't want to stop and decipher a magic one-liner. That comment is a great name for that function.

2. Now that you have a function, write a test. Now that you have a test, your coworkers won't be tempted to tuck extra stuff in that function, because everyone hates editing tests.


I'd prefer the single line magic one.

Exactly because now.. what used to be a menial computation required to get from A to B, has become a Thing, its existence has been justified not just by the declaration of a named function, but it has been blessed by the allocation of holy inodes and filesystem entries and versioning control entries, and oh god no, now it's been promoted to "actually important piece of infrastructure" by the greasy hand of a unit test. It has become a goal in and of itself.. What used to be a worthless piece of "I have Id's I need user objects"-getting-it-to-work has ascended and become immortal. Hours of work will now replace minutes, it adds drag to the entire system, not just in code size and bulk, but in developer mindshare, it exists and must therefore be considered and payed some amount of respect.

It is painless to delete a single line of "doing stuff" when refactoring something.. But alas, in the end, the function call is deleted, but it lives on, either unreferenced or shows its ugly face in other parts of the code, now mutilated and mutated to support "that thing that sounds like what it did but not quite"..

No, flamethrowers alight! Kill it with fire! Let it never be born.

And I'm actually very much in favor of DRY. But that mainly is about repetition, not about spawning as much "structure for the sake of structure" as possible.


That single line of magic is still a Thing, just a thing without a name or any way to check that you didn't make a mistake in writing it.

If this magic single line is a map over a list, that's fine - but I've seen some deeply unholy one-liners. Like, 600 characters for no reason. Don't do that!


Single one liners tend to be quite functional in style and can avoid a lot of side effects that you might get with a 20 liner in a function.


That's fine, you can do that. I was thinking more about, for example, nested list comprehensions squeezed onto one line.


Most of my coworkers are Java and .NET developers.

When we have to get down to the C, lately I've thrown away everything they try to migrate, and write something more sensible.

There really isn't any reason to add comments to this code. No one will ever read such commentary while I am employed. It does me no benefit, so I stopped.


Your way is better because when compiled it is the same bytecode and it’s clearer


Yeah, I see the people OP describes as clever but not wise (and thus not smart).

And I've been one of them, and I now try to avoid complexity if possible and try to make peace with the fact that the smart solution is most often not the clever one.


I think the main problem is the reverse Dunning Kruger effect. It can be very hard to tell what's not obvious to another person when the entire thing is self-explanatory to you.

The two most intelligent people I know write code that works incredibly well, but you can tell it was coded out in one shot based on an idea they had. Makes it difficult to read, but to them it "just makes sense".

A really good friend of mine is like this. When I read over his code, it's highly compact, and makes use of language features that are pretty obscure. The stuff he builds out addresses problem I would never have thought of. But the catch is I can't follow, or understand half his code.

Sometimes though, there's an advantage here. Someone like that can get all the ideas out "on paper" (so to speak), then pass it off to someone who can make it legible for everyone else. There's a lot of value in someone like this, but you need to pair them up with the software equivalent of an editor. You'd be surprised, some people enjoy doing that!


To quote Dennis Ritchie.

"I can't read German, does that make it unreadable?".

Or to put it another way, we don't criticize James Clavelle's novel Shogun because it's difficult for a 10 year old to understand.


The word you're looking for is "mature".


All of this. Truly smart people make things easier for everyone, and usually solve problems in beautifully simple ways.


I think that's overloading the meaning of the word.


That often goes unnoticed and can, to an outside observer, look like a "lazy" worker.


> I can't directly speak to any particular work you're describing, but "smart" people don't usually add significant complexity and aren't hard to work with.

I feel that's really unrelated to how "smart" person is. It's more due to experience when you start to appreciate the simplest approaches to solve the problem.

Many people chase some new and cool features and want to use them just because it is more interesting that clapping out boring code day in day out and that's where you get those overly clever blocks of code. I've seen every level of competence fall into it. Hell, I suspect like 3/4 of k8s and related deployment are exactly that, devs bored and wanting to play with new toy.


To build on your comment…I think picking simple or anti-complexity is a values call perhaps enabled by emotional intelligence and being secure in who you are.

I have met many people whose identity is wrapped up in being smart. When faced with choosing a clever solution or an understandable solution they will choose the former. This is where preserving their identity outweighs empathy for you or even for themselves. Some people also like to be the hero. If they are the only ones who get the solution then they are more likely to be the hero to fix it in some future moment of need.


There is a balance too between simply being older and being young and feisty, though. This smacks a bit of old arguments to 'just use assembly' or the like.

It is true there is an overproliferation of reinvention of syntax, but I have seen often older developers claim something is 'easier to read' not because it is actually so but because they are used to a certain cognitive load.

A good example is an aversion or misunderstanding of properties - these were first popularized by flash as3, informally entrenched against by get/set in Java, and finally enjoyed better syntactical support and syntaxes in C#. I have experienced a degree of pushback that properties are 'complex' or unreadable, when in fact the syntax is evolving to create something simpler and more cognitively manageable.

What is easily understood over time also changes, as newer frameworks become popular or more widely taught and understood, so the esoteric becomes widespread and the widespread becomes esoteric.

A good way to manage this tension for experienced yet aging developers and young yet inexperienced I think is two fold - make regular yet conservative pushes for 'modernization', so that there is room for the new concepts to enter without wholesale refactoring being necessary, while still allowing for the codebase to be understood by both new and old. The other is to require new features, styles, to be well documented, both externally and with in source commenting. This pushes even the new developers to consider the cognitive ramifications of the code they are creating, while also making the code clear to those less gifted or less syntactically experienced.


Oh, dear god, please tell me you mean actual properties and not this unholy pachinko state machine that is getting properties via accessors.


Been writing code for almost 20 years and never found the get/set paradigm useful. I’m fact it’s introduced a lot of incidental complexity when I tried it. Objects and functions to transform objects immutably to the extent possible are much better imo. I don’t use Classes anymore unless they’re static.


Immutability is nice when you have it, however the languages and paradigms you speak of I imagine the OP would also complain are "clever code".

Otherwise it's not a "paradigm", simply having mutable state means you will want to retrieve and modify state on a part of an object/struct/array, in this case the alternative is "plain" getter/setter methods, however these are not guaranteed to even be named the same much less be in a similar area of code. Get/Set properties have two objective advantages that setter methods and raw properties do not. 1. They are always named the same, and thus you can always find them. 2. They are debuggable, where a plain property is not, which is very useful for widely modified properties.

You of course can feel what you like about using them, however I posit them as a fairly neutral example of language evolution where things got objectively better over time, where there are many "stupid", specifically looking at Java, conventions which were/are needlessly enforced for reasons not to do with code clarity at all but rather old people being set in their religious ruts.

There are many, many examples which are much more controversial, but I think it is also illustrative that something as dirt simple as setting or getting a variable can have such illogical and emotional reaction from a wide range of individuals, making up nonsense about how they know the best way of doing things, and claiming things about "young" developers.


A way to make it more interesting to those is to describe simplicity as something hard to achieve and that needs to be smart.


I agree -- If they're really that great and smart, surely better scoped technical goals will wrangle them without pushing them off


Yup, working smart is doing 5 days work in 1 and making complex things simple.


Uhh, please don't listen to any advice in this thread which says "fire your highest performing engineers". You will literally turn your project into a "legacy" system overnight.

You're a manager. Your job is to focus their priorities on business outcomes. If you're not providing focus they will run with whatever pet problems they have with the existing system. That's called doing their job.

I would not worry about style or complexity. Style is irrelevant and complexity is driven by the business case. Don't try to write software that will last 100 years. Its going to be put on maintenance mode and never touched again the second your highest performing engineers leave or are re-orged.


I absolutely agree with the first part of this advice.

As to the assertion that complexity is not worth worrying about, I could not disagree more. I have watched projects fail time after time because of complexity, dependencies, and lack of budget.

Managers should encourage their engineers to spend time trying to simplify architecture and reduce code, infrastructure, and package dependencies. Smart engineers can learn to think simply over time, but this will not happen automatically. (I plead guilty to gravitating toward complexity in the early part of my career, but I have since learned better.)

Managers should place emphasis on using existing patterns wherever possible rather than re-inventing the wheel. Practicing laser focus on delivering value, evaluating solution dependencies with an eye to keeping things simple, and accurately modeling the problem domain in question.

Rather than trying to fight with engineers about implementation approaches, managers should try to guide engineers toward arriving at these conclusions themselves. I have also found that stressing simplicity as a key performance metric for engineers is a useful tool.


> I have also found that stressing simplicity as a key performance metric for engineers is a useful tool.

Some of the smartest engineers I've ever worked with produce code that is so well crafted it feels simple when you look at it, but it's actually extremely clever.

I think the conversation about "clever", "smart", "volatile" programmers tends to align the axis of _code_ complexity with cleverness, but often the cleverness is in finding the perfect simple solution.


"Simplicity is a great virtue but it requires hard work to achieve it and education to appreciate it. And to make matters worse: complexity sells better." -- Edsger W. Djikstra

Complexity sells better because it's cheaper. This is not the, "look at this novel abstraction I wrote and proof of its correctness with respect to our specifications," kind of "complexity" that folks often mean. It's the hand-waving, just add the simplest patch you can to make it work for the business problem at hand, type of complexity. The kind of complexity that ends up with giant balls of "really simple" code that nobody understands entirely anymore.

It sells better for all the usual reasons that driving slightly over the speed limit gets you where you're going a little faster. It's only a problem if you get caught or cause a collision.


Your comment touches on the awol concept of clarity in this conversation: "The quality of being coherent and intelligible".

Balls of mud are the very essence of simplicity (in one sense) yet lacking any clarity.

Clarity is a (bad sort of) hot commodity in an immature yet rapidly developing technical field. In our field this is exacerbated by the fact that the entire field can be viewed as a monument to the peter principle (but thankfully the imposter syndrome is there as a collective salve for us all.)

I think highly intelligent engineers that can penetrate the essence of a problem and come up with effective & coherent conceptual models are a valuable but (in places) untimely assets. My recommendation to such engineers (who also wish to be responsible team members) is to recognize the cognitive impedance mismatch and broaden the 'scope' of the solution to include the human element, and descend to norm if necessary. The ultimate goal is to serve a broader goal, and fighting against impedance mismatch is un-/counter-productive.

My personal red line is the 'big ball of mud' teams.


I don't agree with your points about complexity. Some developers will go off task and introduce complexity when it doesn't need to be introduced. You must have seen this in your career.

As a manager, you should be putting up gates against this (code reviews, and politely rejecting proposals to introduce unnecessary complexity)


> Style is irrelevant

Except when you want someone else to help with maintaining. What nonsense


> "I would not worry about style or complexity."

Given that the OP said that they were working on embedded systems, where reliability, efficiency, and often long support lifetimes are needed, this is very poor advice.


>> Don't try to write software that will last 100 years.

THIS.

I've worked as a developer on huge, multi-year projects and I've worked on rip and tear six month projects and everything in between in the 10 years I've worked as a developer. None of the stuff I ever worked on was never maintained for more than 2-3 years after release before being nuked and built from scratch with some new fangled framework or database or data platform.

When I first started as a developer, building your stuff to withstand the zombie apocalypse was something we all aspired to. We all wanted to be like the Y2K developers. You get called in 30 years after you retired to re-write your code because all these legacy systems are still running on the code you wrote when you were an angsty college graduate at your first development gig.

The truth of the matter is companies don't need something that's bullet proof to last even 5 years any more. I've always felt in some regard, nuking products is done simply for upper management types to prove they're worth keeping around, more than these things need to be rebuilt.


> None of the stuff I ever worked on was never maintained for more than 2-3 years after release before being nuked and built from scratch with some new fangled framework or database or data platform.

OK... but... that's not universal. That's perhaps a symptom of resume-driven-development?

I got a call in 2017 from someone asking about something I'd built in 2003. It was still in use.

I worked with a team in 2015. Looked at their system 2 weeks ago - still using the same base foundation I'd laid out for them.

I'm finishing up a project now rebuilding a system from 2005. There ended up being some IP and legal issues which ended up with "clean room rebuild" as the safest choice. But the system from 2005 was/is still running (for a little while longer).

That you've worked places that rebuild/gut every 2-3 years... I don't know how 'normal' that actually is, save for JS front-end stuff, which seems to almost necessitate it.


>> That you've worked places that rebuild/gut every 2-3 years... I don't know how 'normal' that actually is, save for JS front-end stuff, which seems to almost necessitate it.

I lot of the places had huge portals, e-commerce sites, or multiple transactional application sites. Many of the places I worked transitioned into and out of various platforms.

One place was a huge .Net place, had some run-ins with MS and then decided to move any and all of their stuff completely over to Salesforce. I heard three years later, MS lured them back and they went back to being a full blown .Net shop.

One big motorsports company I worked at had 8 product lines all with an accompanying e-commerce site. They were literally in a 3 year "refresh" cycle. Every three years all the sites would be re-designed, rebuilt and re-released. The company was a huge .Net shop and they always used MS for their DB's and backend. Once libraries like Knockout and Angular got popular, it just became a three year run of JS frameworks/libraries battling it out to see which one we used next. The sites literally went from Knockout to Angular to ReactJS to Vue. By the time they had gotten around to ReactJS, I had already left the company, but the cycles they were on were just crazy and continue to this day.

Another huge corporation I worked for had multiple portals. We literally re-built them all within a 3 year period from scratch, then it was in maintenance mode for a while until we got a new CIO who then decided he wanted to move to a different stack. Rinse, repeat. Less than 5 years, the cycle started all over again.

A health care company I worked for wanted to build a Wellness app for their clients (this was a new thing back then). Their direct competitor had one and they figured they needed one too to keep up. We built that in the span of about 18 months. Gets released, gets rave reviews, we have another year of front-end and DB improvements, everything going smoothly. Apparently the competitor launched a mobile app for their Wellness app. This was about a year before responsive design really took off. They panic, nuke our Wellness app, and then had two teams (one Android, the other iOS) hastily build the app and release it.

Just started working for a huge health care company. First project I was on was to take several different billing systems and create a transactional app for two teams so they could manage everything out of a single app instead of using multiple systems to log into and out of constantly every day. We built that over the course of three years. Then the initiative was to replace ALL the billing systems the team was using with a single system. Apparently the first meeting all the executive types wanted our entire team back on the project to give direction and come up with a dev plan. Again, just about the 5 year mark, all of our work got nuked.

In hindsight, it was never always some new framework. There were consistent external or internal factors (good or bad) that was driving these decisions. Its kind of weird finding out this is by no means normal, but when you spend so many years and the same things keep happening, you just assume this is normal everywhere.


What you’re mentioning is only a particular kind of software, frontend-related. Backend and embedded stuff tends to live for decades.

All major projects I’ve worked on still exist after 10-20 years, with much of the original code still in production. Some of it could use a rewrite, but it works and is being maintained.


To everyone saying "your code doesn't have to last that long", did y'all miss that the OP is talking about embedded C?

There is no nuke and pave with a new framework on an embedded system. At best, you'll see the infrastructure to deliver firmware updates rewritten, but mostly the customer expects the firmware/software to just run until such time as the hardware fails.


Your software probably won’t be running in 100 years, but in 10 years? 15? Absolutely possible.

In fact, after 20 years writing software with various companies, the only ones that didn’t have code older than 10 years were the startups.

But even then, that doesn’t matter. If you’re code is really complex, you’re going to struggle to come back to it in 6 months, never mind 6 years.

Code should be as complex as it needs to be and no more. Write with maintainability in mind.


Most code does not last long.

I have found that someone that is adding complexity is usually showing off, board, does not understand the requirement, is missing something. I usually curb my own natural tendency to do this by saying 'what is the bare min to do this one thing'. Then write what would need to be done in the comments if we wanted it to do those other 'cool 5 things'. Also if you are using scrum or kanban it is a good place to add a story to say 'lets do those 5 things'. Then see if it ever gets any traction. You can write amazing cool code. But most of the time 3 people will ever us it and they will only use it for that one thing they wanted in the first place.

I have been writing code for 25+ years now. My exp is similar to yours. Very little code survives. One proj I worked on if you still wanted to write on it you would need to know watcom SQL (sybase), MFC 4.0, win98s version of win32, and the quirks of those 3 systems. NO one is going to want to work on that sort of project unless there are many zeros on the per hour cost. That was not a small project either with well over 500 modules and hundreds of screens. I have watched project after project either killed or re-written. Code in most cases does not last that long. Of course there are some exceptions. But that is rare, the common path is most code does not last long.


Thank you. This tone of this thread was so deaf to OP's actual requests, advice on perspective and communication, that I actually started to sweat a little.


I disagree with you. You should fire the engineer strategically. Firing the engineer right away does have risk. But there is a great risk long term if the person is in the team and making the team toxic which will repel engineers with better character and better fit.

In a long run, it will benefit team and organisation if the person is fired. I have seen companies shutdown due to the toxicity induced by engineers like first hand. I have also been part of the interview where I was super excited about the product the org was building but rejected the offer after meeting the team due to the toxicity.


You’re describing people who believe that code is an asset, when the reality is that it’s a liability: zero lines of code would be ideal if you could get away with it, but you can’t, so you have to compromise and limit that liability as much as possible by minimising the amount of code and relentlessly keeping it simple, easy to read, etc. Perhaps they’d be more sympathetic to your perspective if you framed it that way?


The whole "code is a liability" mantra needs challenging IMO - it's too simplistic and "cargo culty". It's a misappropriation of a financial accounting term (where Assets = Liabilities + Equity) and liability also carries with it all kinds of negative associations.

It has a value in making businesses aware that production code has an operational cost just to keep it "alive". And it's useful for tempering junior developers who haven't yet absorbed principles like KISS and YAGNI.

But it fails to factor in the relation between code and an organisations ability to make (or save) money from that code. For example the capabilities of your code may be a competitive edge for your business. 10 lines of code which uses CPU and memory inefficiently may end up being more expensive than 1000 lines of code which uses CPU and memory _efficiently_ and leads to lower infrastructure costs as usage grows.

As far as I'm aware the term goes back to 2007 - https://web.archive.org/web/20070420113817/http://blog.objec... - a time where businesses hadn't really understood how to manage software based businesses, so it was a useful concept to help management become more mature about how they think about software.

But these days knowledge of how to run software based businesses is far more widespread - we don't need to simplify our thinking to "code is a liability".


Liabilities aren’t negative in financial accounting, they’re leverage for the business that carry obligations, exactly like code.


Leverage is a combination of an asset and a liability. You gain assets in the short term in exchange for a long term liability.

There is a difference between code and a liability. If a business could wave a magic wand and instantly remove all liabilities from the balance sheet, it would do so without question. They would not, however, do that for code (or the business would collapse).


Something like: software is an amalgamation of the desirable capabilities it provides, which are assets, and the code itself which must be maintained and as such is a liability. Complex and convoluted code represents a greater liability.

Part of your job as a commercial software engineer is to maximize the balance sheet of the projects you work on.


Would you prefer "code is a depreciating asset"?


Yeah but then they just argue with you about whether it's simple. There's a certain kind of person who loves taking complex things and calling them "simple".


Valuing systemic simplicity over simplicity of a feature in isolation is one view that gets me into a lot of disagreements.

Sometimes the simplest overall solution isn't so simple in isolation.


True enough. I think when we say “simple” we often really mean “cheap” (to maintain), so maybe it’s better to cut to the chase and just say that instead.


They’ll say it’s simpler (and better) if everything is a microservice.


It might be that they use simple in relative terms.

Linux could be considered simple given the problem it's trying to solve and yaml complex.


it's more often that they don't understand what simple means for most people

For example they might think that in a mixed-paradigmatic language the "pure functional approach" is more simple even if it introduces more indirection and requires a deep understanding of various more advanced language constructs(*).

Or that the simplest explanation of monad is the one based on PL-theory instead of an explanation based on terms people without an scientific-PL background are more familiar with.

Or people which think that writing down things in predicate logic is just way simpler then writing them down in English (well, I guess thats somewhat me).

None of the "I find this is simpler" points I mentioned are bad, but not realizing/accepting that what is simpler for you isn't simpler for others is the problem.


Rich Hickey has an excellent talk "Simple Made Easy". He points out that "simple" and "complex" describe objective properties. The terms are often (incorrectly) used interchangeably with "easy" and "hard", which are subjective.


Though code is an asset as well... Just not as valuable as people might think. Code is not a liability if it is not used, the liabilities come from production usage.


I agree with what you mean, but I’d nitpick and say it’s not the code itself that’s the asset, but rather the behaviour of that code when executed. If you could refactor and get the same behaviour with less code (whatever that means), that’d be a net win, right? So the quantity of code is making a negative contribution.


Put another way, the feature is an asset, the code is a liability.


i'd nitpick about less code being a benefit (but perhaps that's why you said 'whatever that means') see: https://en.m.wikipedia.org/wiki/Code_golf


I consider code to be a liability, and Git history to be an asset. If something's in version control, there's no need to keep unused cruft around "just in case" it's useful in the future.


Code is only an asset to the extent it fulfills a need that can't be otherwise fulfilled.


I have explained security, maintenance, cost, etc. using pretty much these exact words.

It's really hit or miss when it comes to having any impact.


what a load of crap, you mean linux kernel is a liability. this is typical thinking of folks who are removed from technical work & just consider development as 'cost'. Code & development history is an asset because it stores the time-series sum total of development decisions to get to this point. keeping it readable I can understand but pointlessly minimizing it without the bigger understanding of what it serves because .. 'hey it works' is trivializing it a bit.


Unfortunately only 1 developer in 20 thinks like this.


If an engineer is truly smart, they can be reasoned with. You can use the following concepts to craft an argument:

- Worse is better: https://en.wikipedia.org/wiki/Worse_is_better

- Intelligence is compression (at least in one perspective) https://youtu.be/izqSvm-YAww?t=376

- Many smart developers try to reduce code, not multiply it: https://github.com/geohot/tinygrad https://github.com/karpathy/nanoGPT

- Satisficing https://en.wikipedia.org/wiki/Satisficing

- Perfect is the enemy of good https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good

A perfectionist engineer optimizes their code to represent reality perfectly and wastes a lot of time along the way. Their objective function is the discrepancy between the code and reality, and they try to minimize that.

You can offer alternative objective functions:

- Minimize time to implement a requested feature

- Maximize survivability of the company

A good engineer is one that finds the right trade-off between "the right thing" which might be deadly for the company and "the worse thing" which enables the company to develop features fast and remain competitive.

At least, these are the arguments I use on myself to prevent myself from overengineering.


I agree. If an engineer comes fresh from university/ leet code/ certain companies and hasn't yet adopted the kind of mindset you're looking for, teach them!

If they are actually smart as in „intelligent, humble and curious“ they'll understand and adapt.

During my first two years as a developer, I was also in the „a double for-loop? Not under my watch!“ - camp and wrote a lot of „clever“ code that often was a waste of time or even caused problems lateron.

With experience + reading more about software engineering „in practise” as opposed to „in academic theory“, I learned to prefer solutions that don't use many layers of abstraction, are simple enough for a junior engineer to understand, easy to maintain and actually add value for the business.

A smart engineer knows that engineering time is limited and expensive - and acts accordingly.


An experienced engineer will know it is sometimes better to have a simple and short solution that `when bugged, you can fix it in 30 minutes` than a complete full solution that `you will never be able to find out where did it went wrong`.

Somethings the extension points you designed is never used, but it still has maintenance cost. And that really should be avoided.


I like this general approach. One more to add to the list:

https://grugbrain.dev/


> because as grug brain developer get older he forget important things, like what had for breakfast or if put pants on

Luckily, there is this: https://github.com/everythingishacked/Pants


Yes! Complexity is Apex predator of grug brain developer.


I would show them some Rich Hickey - Simple made easy https://m.youtube.com/watch?v=LKtk3HCgTa8

And hope they see the light


I found this list helpful. Thank you.


I am one of those people - an academic type that likes to over-engineer, and at least partially work on embedded systems. What I've learned after two decades of experience is that it's best to apply most of that sophistication to tooling and supporting software - test suites, fuzzing, benchmarking, quality evalution, code and data generation, prototyping environments, automated reports, etc etc. All while keeping the actual shipped software as simple as possible.


> as simple as possible

"I want that ASAP" just got a much more complex meaning.


NICE


"If you were that smart you wouldn't be working here with me"

A line I used a few dozen times in my career


I can also see this turning sour, though.

A problem with the mindset being discussed is that it makes it hard for people to collaborate, since everything gets complex and muddled. If you just move that problem from the shipped code to the tooling around the code, you haven't really gotten rid of it. There is still a big barrier to entry to contributing to the project, since people don't understand your infrastructure.


K.I.S.S. - Keep It Simple Stupid


Maybe that should be retronamed to Keep It Simple Smart. ;)


I work with many hundreds of technical resources and directly manage a dozen senior ones. I encounter engineers like this from time to time because their ideas bubble up. Your description of them is very good.

Recalibrate your idea of "smart". They may be off-the-scale smart in some context, but are below average smart in other facets. If they weren't, they wouldn't be causing you a headache. It's just that we don't tend to use the word "smart" when talking about the ability to compromise, value effort, work together.

The fault is in your statement "weighing it against the larger system". You need to make it clear to him that it's your job to ensure ideas are weighed against the larger system, if he is unable/unwilling to do so. And that this isn't you calling seniority over him, it's about the skill and responsibility of weighing up priorities. Do that in a way that shows his idea is warranted and excellent inside his frame of context. Explain your objective reasoning and it should be apparent why your decision is correct - "what would you do in my position?". Some of these types want recognition.

Unfortunately, a significant proportion of such people can't cope with this. They'll lobby your peers and seniors to sponsor their idea and eventually one of those will back him. Or they'll just go ahead and do it anyway, if they can. It's why "ignore it" is not an option. This is toxic behaviour that has no part in your organization.

You can move the resource sideways to a new task. Then keep an eye to see if they impose their last bright idea on this task, too.

You can give the resource a task that's more challenging. Or a task that's more in the R&D space.

Sadly, there is prevelance in this type of resource wanting to make his daily job better or more interesting, or engineers in general, and sometime CV embellishment with a new experience. Not enrich the life of the user or the worth of the company.


It’s interesting that you keep referring to this hypothetical person as “the resource”…

I’ve managed people similar to the ones you describe, and enjoyed it. But they do live in another value system. One where “resource” is a dirty word. One in which teamwork has no intrinsic value (beyond the additional economic value it creates).

I could write a whole book on this, but to sum it up I think its mostly just a mismatch between team/management and employee. The former often think of themselves as having the company’s best interests at heart, but when I listen to stories from “the other side” (the “smart” engineer that’s been marginalized / pushed out) it’s not hard to see the defense mechanisms and political behavior on their side.


Your post is good but out of interest why do you say "resource" rather than "person"? It's giving me cyberpunk dystopia vibes


I'm going to have to go away and self-reflect on why I kept saying resource.

It's probably because my line of work (in Europe) is one with project based people who may be independent contractors, large IT company supplied workers, technical users, and sometimes staff. "People" would have been a better word.


This is a pretty good summary. In my experience those people don't understand other's POV, because to them, their solution is not complex. They can be valuable short-term but do a lot of damage long-term, as their goal and yours are not aligned - they are very selfish in that they want to solve difficult puzzles instead of helping the customers or improving the team.


I have this absolute hate for people that talk about employees or coworkers as "ressources"...


I'm one of these people. It's not just a matter of being "smarter", it's the way in which we think. I can analyze a complex system in my head and see the connection between the beginning and the end, most people have to reason about each step. So as a result I'm prone to overcomplicating things, and I have to remind myself to stop and try to think of other ways to do things, what trade offs I'm making and the like. Sounds to me like these guys aren't quite self aware enough for that yet, or they don't understand the debt that comes from increased complexity, maybe they haven't had to rework a system they built years ago or that someone else built.

Tell them there's no free lunch. If they're making efficiency gains they're borrowing from the future in the form of technical debt, they're increasing complexity and therefore increasing difficulty in maintaining and using the code in the future. Remind them that when they take that aspect into account they're not being efficient, and ask them if there is a more efficient way to accomplish the same thing without increasing complexity.

Tell them to take a moment, become disattached from their proposed solution, and try to reason on ways that it might make things harder for other people in the future. That's a key point, because it might feel easy as pie to them. And if they can come up with a way to do what they want without a continued maintenance commitment and another thing to store in their heads forever then you will reconsider it.

Your goal here is to make them better engineers by teaching them to think about the implications of added complexity. Right now their solutions seem so simple to them. They've got talent and potential, but they're not great engineers yet.


Solid advice. One thing that I also became aware of is to not care a lot about workflows, and don't let workflows from the engineers leek into the system.

The reason why I say that is that at some point I worked on a system (first to design and implement it) that for me was very nice and ergonomic, but in the end was full of some quirks and patterns that mostly worked for my workflow. When other engineers joined I clashed with them a lot over those decisions and me imposing a hard structure onto others work/workflow.

When I became a manager and had the opportunity get familiar and re-implement another system, those types of choices and clashes, now from the opposite perspective (I didn't know the code and disagree with all of their implementation choices) really showned me I) the importance of the system design to guide improvements/features and II) how useless it is to dictate how someone should do their job.

I essentially learned that micromanaging sucks, but you get the point :D


Different developers have different values. It is clear in this case these “smart” devs have different values than you. It sounds like they are engineering towards a view of “elegance” of the solution, what is the most compact and DRY way to accomplish a result. You appear to value simplicity over elegance, which makes sense in the brief context you’ve provided.

Convincing them to switch values may take a long time (or never), but in my experience you need to repeatedly stress the values you want the system built on, and give concrete examples of why whenever possible. Give practical reasons why simplicity is better (system stability, debugging, maintenance, etc).

But recognize that for some “smart” people this will be “boring”, and they will never do well. It reminds me of a manager I had ages ago who preferred C++ to Java because his C++ solutions required huge amounts of brain power for anyone to understand, where as the Java solutions could be understood even by dullards like me.


When I first joined the company I'm currently working at, I was a bit too focused on elegance, "proper" tooling/structure, and "doing things the right way", etc. For example, I couldn't _believe_ that we used raw SQL in our endpoints instead of using some fancy state-of-the-art ORM. The company is a start-up, and my previous job was as a SWE at Google, so naturally a lot of design decisions felt shocking to me. I definitely spent a lot of energy thinking about how we needed to "change everything".

Over time, I learned more about the history of our company + the projects I work on, and why they have come to be this way, which has helped humble me a bit, and in turn make me more effective on the team. However, what has _really_ made a difference w.r.t making me more effective, is a recalibration of my incentives - rather than focusing on personally "creating impact" and "enacting change", I shifted my focus to "what does this company need to be successful, and to go public". This significantly changed my thought process when it came to prioritizing work, and has made me easier to work with.

Counterintuitively (to me), that shift has done more to make me a better engineer, than perhaps increasing my technical expertise would have.


This seems like the correct diagnosis to me. "Deeply held beliefs" are at play, at all levels and activities of the organisation, from coding practices, to hiring and marketing. The almost unstated, invisible beliefs destroy collaboration, since it is natural for them to come in conflict.

In a way, if we go deeper into why a religion works, and enables collaboration among large number of people, it is because it homogenizes "deeply held beliefs" through various shared literature and practices.

By extension, if an engineering team must work together in more cohesive ways, "the engineering religion" must be more explicit and there must be higher levels of bonding, more explicitly stated "deeply held values". It is difficult, since it requires excavating deeply held beliefs from individuals, finding common ground, or "installing" at a deeper level beliefs beneficial to collaboration.


> [...] the Java solutions could be understood even by dullards like me.

This is 100% the type of person that came to mind when I read the OP. I'm sure we're all sick of the term "gatekeeping" but when folks consider it a plus and not a minus when their code is intimidating to others, it's really appropriate.


This is the comment I was looking for, it appears to me to be a difference of values and it will likely continue to cause tension( unless someone's values change.)


There is I think a large percentage of engineers like this that are insecure and like people having the reaction you are having and acknowledging how good they are at understanding complex code.

The most effective way to handle this type of person is usually to make it clear you respect their intelligence/are impressed by them, and then to ask them if they can try to apply that same intelligence to a different problem: as near universal legibility as possible.

Trying to minimize context required for understanding code and think about how to put that map in their head in the code explicitly and to get as close as they can to universal language is a really really fascinating and difficult problem to try to solve, and even more impressive to see done.

If they listen to that and get it that type of engineer can transform and start to write fantastic, very legible code.

It think it depends on the type of intelligence they have, as well. In my experience there’s also a large percentage of people like you’re describing that are much better mathematically and visually/spatially than verbally. Sometimes this type of programmer is just better suited to writing the parts of a system that need to be very complicated. Some code is not really possible to write legibly without a bunch of prerequisite internal knowledge, like the deep guts of a game engine, some very complicated computer vision algorithm, etc. Having them stick to that stuff and make overview documents/general comments about whats going on can also be a good way to utilize their skill without as many downsides and illegibility problems.


When I started out as a junior developer, I was put onto a team of 4 other developers that was building a booking system for a leisure company.

I got the impression that one of the developers on the team was particularly smart because he would lock himself away for a few hours at a time and build something amazingly complex that nobody else really understood.

Ultimately, he only worked well when the application was still in development. When it came to shipping it, a lot of the areas of the application that he had worked on had shortcomings or just didn't work. Fixing them was also difficult because of the complexity, which was always made worse by the frustrating thought of "why the heck didn't he just implement this the simple way?".

The work got hard, and the team crunched to fix the problems. He just resigned and left and found another "greenfield" project to work on somewhere else.

In a way, him leaving ultimately helped the remaining developers - we didn't have to keep his unintelligible, not fit for purpose code.

Now, all of these years later and I'm the lead developer elsewhere. I now often have to politely brush off efforts to introduce needless complexity that developers propose infecting our codebase with.

Writing code is fun, and building a caching system might be fun, but in a working environment you need to deliver what the customer wants and is happy to pay for. If the work being done isn't on that path, it shouldn't be done.

I guess I'm sharing this to say, perhaps those brilliant developers aren't that brilliant.


I can offer what much younger me was once told by a senior engineer:

1) With respect to not having whitespace: "Not everyone is as smart as you, and you need to ask yourself, do you want junior engineers working on your code to keep bothering you asking how things work, or would you rather your code by easy to read (and commented) so that they can pick things up on their own?"

2) With respect to complexity: "We are expected to build products that align with business objectives. New and experimental code belongs in your home lab and on your GitHub, not in a production environment."

Depending on how things go with #2, maybe offer to let the engineers spend 20% of their time working on lab projects to improve their product, with the understanding being that the rest of the time they are expected to build products with a minimum of complexity.


I can agree with the spirit of #1 but also I think it has a subtle bad implication. You do want your juniors to talk to you and you should want to talk to them. You should also want to push them out of their comfort zone (slightly at least) so they can grow.

For #2, I don't think it's fair to say complexity is always equivalent to "experimental." We're getting close to conflating code that takes skill to write with code that has no benefits or will be buggy/experimental. The OP doesn't really deny that his engineers can write this code without failing at it or that it wouldn't improve the product in a measurable way. The post in regards to complexity is really more about the spirit of your first point in which he thinks some subset of his team can't easily deal with this type of code.

I would say that "complex" code that provides a measurable benefit and that some of your team can "wrangle" isn't necessarily a bad thing. If you want your product to be differentiated and better versus your competitor's product you're going to have to do this. If we all program (100% of the time) solely to lowest common denominator on a team(and I don't mean this disparagingly) then the company's product can only be as good as its "worst" engineer.

Otherwise, we can all get off of this site and build the same todo app from the same step by step tutorial :)


Generally agreed with this, and I had a similar experience.

I think overall it comes down to trying to help them build empathy by showing them that they aren't the only one that will have to interact with what they build, as they are a part of a team.

An easy way to start is, like the parent suggests, with showing "How does making it easier to read or reason about ultimately benefit you?" (e.g., not having to be asked for help by junior engineers). The downside of this is it's kind of abstract, and ultimately a selfish motivator ("what benefits me?" over "what benefits the team?"), as another commenter mentioned.

One option that might be more tangible and team-oriented is to discuss design options as a team. Hopefully in doing so they can understand the complexity in their approach as other people ask questions. If you're able to structure in such a way, one trick here is to separate the design phase from the actual implementation phase. So, whoever designs the approach isn't the one that implements it (within reason -- you could also pair program here, with the whoever designed it as a reviewer and not the primary).

Some of this is also about them realizing what is obvious to them is not obvious to others. One tell here is if they use "why don't you just..." a lot when asked questions.

One phrase I use a lot on my team is "don't be a hero". Heroics in a team setting (willingness to write overly complex features, take on indefinite maintenance of code they wrote so others don't have to reason with it, etc.) are generally detrimental to the team overall. If they find themselves having the need to "carry the team" a lot, you could direct some of their energy/problem solving towards how they could help up-level the team overall or fix team processes.

Anyway, a bit of a ramble, but that's my 2 cents. YMMV.


Adding complexity is fast and easy, adding simplicity is slow and hard.

Any codebase that is simple to understand and modify is a second party's canvas to add complexity in record time, for the purpose of telling a third party they added complexity in record time.

Imagine you get permits, rip out a bathroom, choose tiles and spend a long time cutting them. Someone comes in overnight and superglues them to the floor, and not even the pattern that was intended, but they did the main work and in only a few hours.


Or you need two feet of pipe to hook up the sink in a straight line but you come back the next day to see your “smart” pipe fitter has made a 10 foot pretzel


> They have a big appetite for adding complexity to systems .... What was notable, though, was his immediate willingness to write that feature.

From your descriptions, it seems less about "adding complexity = good", and more about "solving things in a neat way = good" (for some definition of 'neat').

> Do you have any thoughts on how to work with them in a productive and friendly way?

I'm not sure you've articulated the problem very well?

It sounds like if they left & the code was handed to you, you'd be concerned about hard-to-spot bugs in the sophisticated code. -- But if the code & its correctness is your colleagues responsibility (& not yours), what's the problem?

> It boiled down to me advocating for more whitespace in his code and him arguing that adding whitespace made the code harder to read.

I think you came to the right conclusion about the differences. But, you might enjoy this blogpost from Steve Yegge:

http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.htm...


I think what you’re trying to say is that these types of solutions are fine, as long as they are decided upon by the entire team, and not just a single engineer: long-term maintainability is key here.

I’d also argue productivity is an issue: “neat” solutions may take much longer to develop, while the effort is not really justified. E.g. starting out with a system based on CQRS which is just a simple CRUD app.


Wow. I would LOVE to only work with "noob" programmers who nicely explain their reasoning for complex code. Comments are easy to ignore anyways.


Jesus fuckin Christ. I tried to read this blog post about how newbies make their code comments too verbose, and the post turned out to be longer and about as interesting as fucking Dianetics.

tl;dr, young programmers, ignore that schmuck. Please keep writing nice long comments to your heart's delight. You will thank yourself one day.


One of us missed the point because I just added that to my permanent bookmarks as an excellent explanation of why some people write overly verbose (and hard to read and thus maintain) code, while others manage to write the same thing in a single, understandable screen-full.

" I would rather puzzle through a small, dense, complex piece of code than a massive system with thousands of files containing mostly comments and whitespace" <-- This, a thousand times. _I_ simply don't have the capacity to load giant nonsense class hierarchies into my head and actually execute such a program.. A small machine that I can actually see on on the screen, that I can manage..


really... if you've ever tried to write your own functionality into something like wordpress or bootstrap or whatever, you'd rather have that all in a single code file with less white space or comments? Would that make it easier to change the positioning of a particular dialog box? I thank God all the time for the white space and long comments left by writers of those kinds of libraries. Maybe those seem like trivial examples, but they're huge libs that don't often need a lot of changes; yet when you need to change things, they make it quite easy to find.

[edit] as I wrote that, I just realized that younger devs might actually look in horror on the idea of directly editing libraries like that for particular deployments because the tooling or shop mentality so forces automated upgrades that could overwrite custom changes... and institutional memory being so short, no one might remember the change some dev made to a bootstrap file. heh. But that's like someone calling themselves a mechanic without ever modifying an engine. You write a note, commit it with a custom marker like #weModifiedThis, and don't upgrade the library for 15 years or until you're dead or retired or the company goes out of business. Done.


There's a balance to being overly verbose and isolating _EVERYTHING_ from _EVERYTHING_ to such a degree that it's a major travel all around the codebase to follow one little path through a single call, and cramming _EVERYTHING_ into one file.

I'm arguing for a balance.


This is true and reasonable for small systems and code bases, and small teams. But it’s not generally a good idea to argue for a relaxed balance in large systems or code bases, nor with large teams, where you can travel all around the codebase via roads you built and mapped, or you can travel all around the codebase following bugs into code you don’t know caused by lack of isolation. Eventually, if you don’t isolate, then there’s no avoiding traveling all around the codebase, it’s just whether you want that to be a pleasant journey or not. Of course it’s really hard to argue over programming platitudes without any specifics in front of us to discuss, but chances are high that experience over time with large systems on large teams will make you reflexively avoid arguing for balance when it comes to either comment verbosity or code isolation.


> about how newbies make their code comments too verbose

I don't Yegge is trying to make this point.

Instead, he's making a similar observation to the discussion OP had about whitespace/code:

Yegge reckoned that someone who's very familiar with the program/domain will want to have very dense code, so then they can make as much use of screenspace as possible.

Whereas, for someone who's unfamiliar with a domain will benefit from seeing less code on the screen at once. It will be easier to digest.

I don't really see that as a value judgement where "comments = bad".


I think arguing each case individually is a trap to avoid. A method I've used with lots of different groups of people, from groups of 4 year olds up, to dev teams, to groups of CEOs, is at the start of a project get everyone together and mutually come up with a set of ground rules around standards and conduct. So things like - we will use this coding style, we will ensure that every function is documented, we will not pursue premature optimisations as long as we are under x power budget, we will not introduce complexity that will be hard for others to reason about etc.

You will have ideas about what these standards should be and you should feel free to propose some yourself during the process, but the aim is not to impose them on the group but to come up with something cooperatively upon which you get consensus. Then write down what you have agreed, stick it in a prominent place and make sure people stick to it. The process should only take about 10 minutes.

Then whenever one of your engineers comes to you with something that goes against the mutually agreed contract you can just flat out say - no, you agreed we wouldn't do that and move on. If something isn't covered by it then have a discussion.


As the engineering manager you should implement an automated code formatter in your CI checking. I think clang-format will do this for C. Doing this simply removes this whole class of conflict from your team.

This is a program that you run which will deterministically re-format your whole codebase. The CI checks on a PR should not pass until the PR diff matches what the formatting program says is the correct formatting.


Have you tried explaining it to them in exactly the way you have written it here? What was their response?

In my experience, this happens quite often with people coming from academia because they're used to write throwaway code that doesn't get read by others and doesn't need to be maintained. It's only used temporarily to publish papers. However, most of the people I have worked with were aware of the fact that their code didn't follow software engineering best principles, they just didn't know how to do it better.

Another factor may be ownership. Sometimes people are excited to implement something because they like the idea of owning part of the stack, e.g. the caching implementation, instead of constantly implementing minor improvements in other people's code. Perhaps these people are looking for ownership of something more so than a specific complex solution?


"Objectively better" and "brittle" are at the opposites.

Perhaps they are not too smart but instead "too generative". I.e there are people who generate a lot of code but then don't do any weeding in what they did. If they continue to be responsible for that corner of the code base then everything might be fine, but if other developers pop in and out of it as well, then it will get increasingly difficult to manage.

I'd say mark out the area they are allowed to do this and keep them within those limits :). They probably will enjoy this as well as they'll have something they have autonomy and responsibility over.


One thing I observed (in me and others) that when tasks seem too simple at first, your brain automatically tries to add a bit more sophistication to the whole project - so you do not feel that dumb, and also to not look that dumb.

After a few years maintaining systems, I do not use the word "simple" for anything software or computer related anymore. I'm glad if something works as advertised - and I'm delighted if I see people putting in effort to make someone else's life easier.

People, who appear smart may well indeed be just a little frustrated. Not the person who makes things more complicated or ask complex questions is smart - that difference seems to escape some of the even smartest people.

As for working with these people, I don't know. You have to endure them, make them aware of the tradeoffs that are made, in the best case show them something simpler, that accomplishes the goal.


What a lot of comments here are missing is that complexifiers can be turned into simplifiers. The key realization is that they are bored by the assigned work and want to do something challenging, not that they want things to be complex per-se.

There is a hierarchy of code quality by difficulty, and it takes increasing smarts to ascend the ladder here:

1. Simple but bad code. - the developer doesn't understand the problem and just writes simple straightforward and wrong code

2. Complex bad code - the developer understands the problem and tries to solve it, but is just making everything worse.

3. Complex good code[0] - the developer solves the problem convincingly, but in a complicated way that perhaps only they understand.

4. Simple good code - the developer realizes a simpler way they could solve the same problem and writes it in a way that allows others on the team to understand and maintain it.

Your developers are currently at a 3, and you need to push them to ascend to 4. If you get your smart devs using their brains to remove complexity from your system with stunningly clever simplifications, everyone will be better off. And it can't be faked, it's truly difficult to solve hard problems with simple code.

[0] "I object! Complex good code is an oxymoron!" Listen, for the sake of this comment, "good code" means all other measures of quality other than complexity. Efficiency, solving all problem constraints, well commented, etc.


> - They have a big appetite for adding complexity to systems > - They also have a big appetite for adding work to their own plates

This is actually in part a management issue, and process issue.

Whoever is managing the team's work shouldn't allow developers to go rogue and start doing whatever they want. Everything is a card. Everything is prioritised. If the work isn't going through a sanity check and being thought about in the context of everything else then the developer has gone rogue.

Once you have everything being carded up properly (requirements, acceptance criteria etc) then quality control happens during card show-casing / pull-request review. If someone has gone beyond the requirements, don't let it fly during pull-request review. Separate pull-requests for separate cards - no combining them all into one, no working on multiple cards at a time.

Stick to the process and be an anal card and process nazi about it. Don't let things slip.

> - Their code has no consistent style

This is a team standards issue. You need to get together as a team and together agree on a consistent style. People's code who breaks the standard shouldn't make it past pull-request review. You can also introduce linting tools to help enforce the standard.

Assuming you have them, get the team lead and PM in a room together to discuss how to put all of this together. You might find that one of the bigger issues here aren't the team members themselves but whoever is leading the team.


One trick that I used in a similar situation that was simple and effective worked like this: (imagine a conversation with engineer)

Me: Hey, I got a question I was hoping you could answer. What do you think is harder, writing code or reading code?

Them: That depends who are we talking about?

Me: Idk, I mean it sort of generally. Let’s start with which you think is easier/ harder for other people.

Them: Probably reading code.

Me: like how much harder?

Them: Maybe 2-3x harder ———————-

Then, next time you have a one on one, or you do like a team meeting bring up this point and say that if reading code is 2-3x harder than writing code, then we should strive for our code style to be within an understandability budget. If we write code at our max intelligence, let’s say one of your team mates has a super 10/10 intelligence, then it requires a 15/10 to understand it and it’s therefore out of budget.

I’m an engineer and I’ve used different versions of this argument to great success in convincing people as to the merits of why it’s good to write code that’s intentionally “dumber”.

Roadblocks that I’ve had in the past have come down to communication issues, where in one situation in particular a fellow engineer didn’t want to give answers to the question or be pinned down to even rough easier/harder for reading/writing code. In general, engineers like this don’t understand how they’re perceived by others and they can’t understand how their work affects others, and what can you do? I’m not sure, nothing works 100% when it comes to people.


You can gracefully accept input and not act on it.

People often have a need to be heard, to expose to the world what's going on inside their mind, to be appreciated for their ideas. You can serve that need in a friendly way by listening attentively and being genuinely curious. You can also suppress that need inside yourself and avoid responding with your own critique and argumentation.

You just listen, ask some questions, show that you are interested, thank them for their idea, and then decide for yourself if you want to act on it, and if you don't, then don't.

In most cases the topic will never come up again. If they nag, just be very positive, remind them that you really liked their idea, that you identify what's valuable about it, but don't make any commitment to acting on it.


I can understand the approach; avoiding any confrontation, but from the other side it will seem like gaslighting.

I suspect you need some balance in the time it takes to debate these ideas, so it might be better to ask them to put their proposals on paper with a word limit and a time limit to debate the ideas; they are heard, and not only that but the ideas are debated. If you time limit not only the time available to debate ideas for each individual idea but also limit the time for debate overall it will require your reports to think selectively about what ideas are really good and which ones are worth the time to pursue.


Firstly this trait is not at all exclusive to smart engineers - everyone falls into this trap at some point.

I think one thing that's helped teams I've lead/helped lead in the past, and helps with a huge host of team working issues too, is by setting norms, and documenting them.

For example, in your team's "norms and values" or "way of working" doc, you could include simple things like coding style (in JS land most people just say "use AirBNB style" here).

But it can absolutely also have things like "don't add unnecessary complexity".

Reading your post, I think you can even quantify it too. You mention being able to count the number of bytes or microwatts any given approach will save or cost, that it's objectively measurable? This is great - you could decide (as a team, or let the team lead or whoever else decide) what the approximate limits should be. Complexity itself can also be measured (e.g. cyclomatic complexity). So you could actually be "real engineers" and decide what the trade offs are for your team, or for your target hardware.

All of that aside, it's also good to try and keep an open mind to other peoples' solutions and communicate with each other when deciding what the best approach is. Open, transparent and prompt communication is worth so much, so make sure your team keeps working on that too. (I've worked with some embedded teams that were distributed and almost never spoke to each other. It made things... interesting!)


These two statements are not compatible:

> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with. The proposed change typically does indeed make the system objectively better

> But the overall system becomes a little more brittle, and a little harder to reason about, two things that are much more difficult to measure than memory and power.

Complexity is your enemy. Complexity is something you need to have a strong motivation for, and if the system becomes more difficult to maintain moving forward it is not, in fact, objectively better. In the long run, you're going to spend more time maintaining code.

In many cases these engineers are good at optimizing for something, and they enjoy doing that. Optimizing for something like memory or power is, as you said, easy to measure and easy to "gamify" by improving metrics. What you need to do is encourage these engineers to find other metrics to focus on, even if they're a little softer. For all their faults, getting engineers to consider things like total LoC, complexity metrics, etc as something to work toward improving may get them to redirect their focus in more productive areas. It's not that their existing focus areas are bad, they're just an incomplete view of the overall priorities.


I've worked with these super-smart idiot savant type engineers before and often butted heads over stuff, and later in my career lead teams that have those archetypes.

A few things I think - one is stress that they might be clever enough to understand and manage that kind of complexity, but you personally aren't, and would prefer styles, solutions and techniques that are comprehend able by mere mortals such as yourself. This is hard if not impossible to argue with. After all, you need to be able to understand it, because if they leave or are unavailable the maintenance burden will be on you / the rest of the team.

But the flip side is these people are usually very good problem solvers and prolific, so the more you can harness that, the happier everyone will be.

Some of my regrets include stalling a PR for being overly complex, resulting in it not getting merged and deployed for months, when the code would have saved 10k/month in server costs. When I tried to re-write it myself to be simpler I failed, so it was arguably necessary complexity. With that said the team that took the code after us, removed the feature entirely as it was a complicated mess - that was probably the sensible but outside the box solution.

Another one was early in my career working with a senior who liked short/scope relative names. I thought it was bad naming at the time, but now I realise that if you do it properly, the shortness itself can be semantic.

The biggie for me is tests, many people dislike writing them, and occasionally the smarter guys can get away without them, more so than the average. But long term, this creates a nightmare because the team will lose confidence when making changes. Convincing people to write more tests is difficult and I haven't worked out a great way to emphasise why it's necessary.


My last project had a lot of overly brilliant and smart engineers. There was a lot of code consistency on that project, but the app ended up becoming so complex in nature and overengineered that I didn't know where to begin. We added so much tooling in our testing pipeline that tests became a constant failure in our devops pipeline when things would timeout. Something that would take only a day to push and build, took way several days to complete in the future

I'm all for keeping things DRY - but sometimes it can go too far. Too many abstractions leads to abstraction-hell.

On my current team, everyone likes to keep things a bit simple, which is a nice change in pace. I don't have to go through a chain of 7-8 files to build a basic CRUD feature. I don't have to wonder what some weirdly written but compact code does. I don't have to think as hard and can focus on what matters


Some concrete policies (I know the type):

- focus on very specific examples. "We did this (here's the code from the git repo N years ago) and that's how it went wrong".

- if examples don't present themselves, sometimes it's worth letting people do "over complexity mistakes" and let themselves get burned, if you can afford it.

- in such cases lay out simple criteria for success and failure, like "it's going to take too long" or "it's going to be too complex to modify". Write them down, in private, then pull out when it blows up (not necessarily to be an A-hole, just being able to quote the discussion gives you much more credibility in a post mortem).

- Sometimes a bit of "it's too clever for me" works, depending on how humble you're feeling...

But ultimately KISS works because it works, which is hard to see without reference to practical code.


It's a tricky balance between keeping smart engineers happy and keeping things simple.

The underlying problem is that you don't need that smart of an engineer and he's being underutilised.

You should move him to another team where he can do meaningful work without having to come up with complications of the existing codebase.

You can also put more on his plate in the form of people work / leadership; it's a different skill to master and if you constrain the time he has available to do work, he'll be forced to keep it simple.

I definitely had an "overcomplicating" phase (whether to play with something new or just because the job is boring). Right now I just constrain my time for tasks, by doing a lot of different things and I need to keep things as simple as possible.

I still write a few 2000 characters throwaway one-liners every once and then when I get something done quickly, though.


I want to support the proposed solutions in this comment.

A long time ago I was like the engineer that is described by OP. Basically what drove me was the search for engineering /coding challenges.


The grug brain developer website might help articulate some of the ideas you're trying to communicate to your "smart" peers.

https://news.ycombinator.com/item?id=31840331


If you don't mind my asking, what does this mean? I've seen it a bunch lately and haven't been able to look it up because I haven't figured out how to convince Google that I want to search for a literal "* * *" and not wildcards.

Edit: When I wrote this I just saw a comment with the text "* * *".


Strange at no point did I have that as the comment. I haven't edited the comment. Maybe it's the 2 minute delay I have on my comments?


I have set up that email service that sends you a message when someone comments on your post and I've noticed an increase in the * * * notifications over the last while.

I think it may be a side effect of that delay feature or a change in the HN site that renders these comments in a way it shouldn't?


Thanks. I love that service!


This website is gold. It manages to be at the same time funny and full of actually smart observations.


How do you communicate with them? I'd start there. Is it over IM, email or in person, zoom calls? I'd try to get off 'written' mediums and get on more personal medium.

If you are REALLY serious about fixing this, I recommend a book called "Non Violent Communication" https://www.amazon.ca/Nonviolent-Communication-Language-Life... Satya Nadella claims it was one of the reasons he was able to turn around Microsoft.

The way you express your needs may resonate better if you adopt


In my experience, these types of people never really learned software engineering beyond "don't repeat yourself." They learned to code and they're smart enough to come up with clever solutions to complex problems. They don't understand the value of maintainability because they enjoy figuring out complex code.

The software industry often values this–myopically, since their opaque code and misunderstanding of DRY are sure to cause bugs. Some junior engineer five years later will misunderstand how coupled some 300-line function is with unrelated components and introduce a bug while implementing a feature. It happens all the time.

I've seen managers who encourage this and I've seen managers who see the big picture and value simplicity and maintainability. Beyond being in the right environment, it's hard to mitigate the problem. These programmers don't think they need to learn anything from you and are unlikely to ask, and unsolicited advice is not likely to be well received. I've sometimes found that leading by example can help, if they notice that the code you contribute is more pleasant to work with. Perhaps pushing for more pair programming on your team so that members can learn from each other.

Ultimately these people are more interested in solving puzzles than producing software that will stand several years from now. If you can present that challenge as a puzzle they may start to find satisfaction in it, but if not then this will weigh on more than just you and is bad for your product and company.


In my ideal world all engineers get to do the work they find interesting that also helps meet team demands. In the interest of not fostering resentment or loss of energy in those contributors I’m wondering what kinds of incentive, goals, metrics, and policies might make you all happy.

I would focus on the end impact instead of the implementation. If someone wants to save a few bytes of memory, why? You state it doesn’t seem worth it to you. Is it a value your team actually measures? If not, try starting there. Having conversations about what’s worth optimizing and why will leave everyone feeling heard.

I believe most people want to do a good job and want to have an impact. If they see that there’s little gain in minor optimizations then maybe they might stop code golfing.

Another (likely) theory is that they just don’t see the complexity in their code. To them it’s not complicated. If that’s the case what heuristic could we use? It’s my experience that tested code is easier to modify, so maybe let them write complicated things, but also make it a requirement to do the leg work to make it more maintainable.

Last option that comes to mind: pair with them with the explicit goal of making the code easier to reason about. They’re stuffing the curse of knowledge, you’ve got beginners eyes. Together you might choose to rewrite parts, add tests or lints or docs.

Go into the process expecting change from them, but also from yourself. Oh and also if you’re struggling to bring this up without yelling at people I recommend using the non violent communication (NVC) framework it will help you to be heard. Good luck.


Eh, let them live with their "smart" code:

What happens when they leave it for a few months and come back and forget how everything works?

When a client encounters an issue in the field and they have to debug it with "It doesn't work, yo." as a problem description?

When a coworker tries to modify it and breaks everything because they can't figure out how it works and there are no decent tests?

Eventually, they'll come around :) Or maybe there is no saving some people and they should stick to R&D...


While this is tempting, it falls apart as soon as the development team matures and grows beyond more than a few people. What often happens especially in larger organizations is that bugs and/or changes come up and someone ELSE has to dive in and try to figure out what's going on. It's at this point that dense uncommented code or code that employs every preprocessor trick in the book becomes a huge liability. That "smart" developer just caused an increase in the time it takes to do code maintenance because the poor axe-wielding sap who has to look at it now has to spend a bunch of effort just to figure out what's going on.

Some of you may be thinking, "Then you didn't hire enough smart developers!" (for whatever definition of "smart" we're talking about here). To that I would say, "Maybe not, but I'd rather hire a solid, dependable developer who knows how to write maintainable code over some sort of savant any day of the week."

I've managed a lot of different developer personalities over the years, and the "smartest" ones nearly always produced the worst code for the business overall. In addition, while they were doing this, there were often other quirks that came along for the ride, like 'malicious compliance' with the design, or checking in three features you didn't ask for along with the one that you did. Sometimes it takes some uncomfortable conversations to get these people working with the team, and sometimes it's just impossible. In the latter case, this person just becomes a liability to the team and should probably be encouraged to move on.


When thinking about competency, I make a distinction between intellect and smarts. People who I consider to be intelligent are those who can think about many facets of complex ideas, and can discuss them at the very least. Smart people are those that can make good decisions about what they should apply their intellect, however much, to. Brilliant people can execute on sophisticated ideas that are worthwhile, or worthless, that may or may not be complex.

Impressive people but not necessarily brilliant people can execute on either many worthwhile relatively simple and perhaps demanding tasks OR something like a really long-running, really complex, and totally worthless idea that provides nobody any tangible value.

I have a friend who's an electrician for example. It's not an incredibly intellectually out-of-reach discipline, but somewhat so. He seems to regularly take on manly projects like redoing his kitchen or his motorbike, and finishing them. Again, he's not building camera sensors from scratch or developing a new machine learning framework in his spare time, but he gets it done. I suck at that. He's smart. But he's probably not a genius.

Meanwhile, a former colleague and I would regularly chat about type theory and datalog and Coq. It was quite a challenge to understand what he was talking about without a lot of background knowledge on that subject, and the value it could possibly create beyond curiosity. He was quite intelligent, made a series of weird academic choices that favoured deep information theory subjects, but looked like you'd expect and had almost non-existent social skills. Maybe smart, mostly intelligent.


Code only readable and maintainable by one person on your team is less than worthless: it is a trap that turns into techdebt (something that people will only be able to slowly work on), create more tech debt (team members will work around and duplicate functionality rather than touch it), and constrain your future timeline (as it becomes dependent on gaps in one person's schedule to add/fix/change old features).


> they're the one taking responsibility for doing the work and ensuring its correctness

But that's not the case. They're taking responsibility for _initially_ doing the work and ensuring the correctness _for the cases they've thought of_. Past that, they're adding mental load to every developer on the team. And to the person that needs to maintain it.

If it's a caching system, what happens when some other person is working on something that doesn't play nice with caching? What if they don't realize there's caching and they waste a lot of time trying to figure out why their code isn't working? What if they need to bypass caching to get the correct results; so they need to understand the caching system enough to do this? Does it even support it? Is their code now coupled to the caching system?

What happens when things about the system need to change? Who is in charge of that change?

Adding complexity to a system doesn't just impact "the person that wrote that complexity at the time it was written". It's an ongoing cost, forever, until it's removed. It needs to be worth that cost, or it shouldn't be done at all.


It's hard to judge by what describe if you are the "smart engineer" or the others are the "smart engineers".

"In a past role, I got into a debate about code style with the smartest person I've ever worked with. It boiled down to me advocating for more whitespace..." - This example puts both you and the engineer and the company in a bad spot as it's a complete waste of time to discuss something like this (if it's discussions over discussions). The tech lead should should decide once and then everyone should comply with whatever way they decided (potentially after one short discussion).

If smart engineers consistently propose un-necessary complexity then Im sorry to bring it, they are not smart engineers and you have nothing to do but run. It wont help to discuss it and try to convey your message (unless you are the CEO but even that wont help as you can't monitor everyone so honestly if you are not the CEO just run and if you are the CEO just replace the team).

So really hard to tell without being in the place who's the smart engineer but if you are the smart engineer then run :) if they are the smart engineers then stay and learn.


I don't have the source for this quote, but it does make some sense to me:

”Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” – Martin Fowler

Anyway, I think there has to be a decision/ranking on the importance of having

1. happy programmers & excellent code 2. code that any(?) developer could jump in and maintain

To me it often boils down to not making simple shortcuts due to laziness unless it buys time to market or has some other significant upsides.

Making a system flexible can often be done in a non-complex way so I would challenge then need to make software complex. There is often a trade-off between efficiency and maintainability. If the efficiency route is always preferred there could come a day when the developers quit and others have to maintain what they feel is a mess of code and want to rewrite it. So my vote would be to keep the complexity low (and flexibility high!) unless there's a concrete benefit of allowing the complexity to grow.

You could look into various design patterns to keep code flexible while keeping complexity low.


The longer I do this job, the less I value extremely high intelligence. In the end whatever you work on has to be able to be picked up by someone else, so unless you're working in very specific fields, there's not a lot to be gained by being extra clever. Consistency is a lot more valuable. As you said, being able to reason about a system is incredibly important. That can be accomplished in a lot of ways, but the _best_ ways I have found over the years are:

- Document everything, and have a system for keeping documentation up-to-date (stale documentation is often worse than no documentation at all). Often it's possible to include a README.md in the same folder as the code it is talking about. You can link to it from a parent directory to keep things discoverable.

- Have a test suite for anything you need to be able to reason about. Also, design your test suite so that it defines your application's behavior with positive assertions (i.e. when <condition> then <result>)

- Focus on solving a "class" of problem and document over-arching solutions. E.g. littering your codebase with a bunch of one-off optimizations may improve your application's performance, but the goal should be to have a consistent way of building the application so that these improvements are essentially a free by-product. For instance, in a data-heavy environment you may want to write some abstractions around bulk insertion and paging that can be applied universally. This way of problem-solving leads to good consistency and less cognitive load, because rather than a giant block that I look at and think, "What is this thing? oh, that's a paging implementation, gross!" I can instead recognize almost immediately what this thing is ("Oh, this is paged using PagedQuery, cool!") and also have other examples of its use around the codebase I can pull from to do whatever it is I'm actually trying to get done.


Just my 2 cents, as I have been on the other side of the table:

- It could be that you misunderstood the argument. Maybe the engineer wanted to avoid the old 'static global global' structures, which are still omnipresent in embedded C code, and which is followed by especially bad engineers. It's not about memory at runtime here; it's more about encapsulation, state and testability

- If that is the case then let the engineer do it. Code quality can be measured by how easy it is to remove a feature

- I've went into numerous turf wars about code style. I lost all of them, even if I won some battles. At one company, they were paying one full time engineer to manually reformat the team's code.

Don't play this game. Slap on astyle or clang-format. Enforce it. End all discussions with "Then you change the style guide and check with other projects". You win in either case.

- Don't ever argue with people who organise their code in neat tables with tabs and spaces

- Don't you have a product to ship? Make that clear to everybody, break it top down, and let the engineers fix that stuff.

- Remember, they are doing the work, you are just organising. Why should the code be easy for you to read?

- Maybe that complexity just exists for you, not for them. An isolated system may be as complex as it wants to be

- I'm not always right. And other people as well. We need room for mistakes. That lets people grow. I did a lot of mistakes, and I will do more.

So even if I know for a 100% that my colleague has chosen a bad path with bad complexity and a lot of work further down the road, I still let him walk that path. He needs freedom. All I can do is support him and protect the rest against the fallout. Other people offer me that freedom as well.


> - Don't ever argue with people who organise their code in neat tables with tabs and spaces

That is just a workaround for the problem with formatters.

Formatters have no information of logical context.

Structs initializers can become unreadable after a formatter has enforced its whitespace rules. Easpecially arrays of structs.

Instead of some simple struct you might end up with alot of code to just please the formatter.


Pedantic, obsessive coders are the worst to work with. I'm guessing they also lack social skills and awareness. I agree with your examples, KISS and code should be clear and easy to read, think about others who have to pick up your work in the future.

I worked with a guy like this on the last contract I worked, ended up resenting him, really poor social skills and would just obsessively code all day. Another older guy would get lost on a refactoring project for months and then the manager asked me to review it, he's spent so long just refactoring and moving stuff around but it added no functional benefit, that's a lot of time and money to the business lost.

You can set engineering guidelines, PEP8, or enforce code rules via CI pipelines, at least then if they become pedantic you can just refer to the rules.

Ultimately I think it's a combination of introversion, obsessiveness, lack of experience in coding for others, being pedantic and social skills.


> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with. The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness. But the overall system becomes a little more brittle, and a little harder to reason about, two things that are much more difficult to measure than memory and power.

There's a lot of fine points made here already by other commenters. I will say that long-term maintenance of software is a non-trivial concern. If you can identify that a change is good in terms of, say, power consumption but bad, say, in terms of making the system more brittle you now have an optimization decision. Do you _need_ better power consumption enough to sacrifice developer time long-term, potentially introducing bugs in the future?


"- They're brilliant, I mean very smart people (in an almost academic way?)

- They have a big appetite for adding complexity to systems

- They also have a big appetite for adding work to their own plates

- Their code has no consistent style"

These statements contradict each other, or at the very least these people are not good engineers, even if they're smart in the sense of being able to deal with complex ideas. Good engineers do not code with an inconsistent style, nor do they add unnecessary complexity when it was avoidable, just to satisfy intellectual curiosity.

The real smarts are to be found in simple, clean, clear code with obvious lines of control. Great code can look almost 'dumb' to the 'fresh off a CS course' grad. This is the difference between cleverness and the wisdom and the good taste to know the right balance to strike in code.


Maintaining systems is a balancing act. Your take seems kind of at the conservative end of the spectrum. Whether a certain degree of complexity is 'unnecessary' is so subjective and based on values and experience. You might be able to learn a bit by being more flexible. It's easy to get into a habit of avoiding changing a system because of it's complexity because there are definitely benefits to doing that, but at some point the business starts to see that system as a problem if they can't make improvements and add features at the rate they'd like.

To me the whitespace/code style issue is separate. Personally I think there are more benefits to letting people make these choices according to their own preferences rather than trying to come up with some consensus and then enforce it.


> Your take seems kind of at the conservative end of the spectrum.

Nah. Their take is from an engineering standpoint. The type of brilliant people they're talking about can reason about terrible code, but most software engineers aren't like that, and it doesn't make sense for these brilliant people to ignore good engineering practices because no company can afford to hire only geniuses.

> Personally I think there are more benefits to letting people make these choices according to their own preferences rather than trying to come up with some consensus and then enforce it.

Having various styles of code on the same codebase is inefficient. Most styles are chosen arbitrarily (e.g. where to put opening braces in C) and you should follow whatever style the codebase uses. Once you push code to a repo it is no longer yours. There is no engineering value in mixing in your own preferred style.


I respectfully disagree with you on the whitespace/code style issue. In most teams, you are writing code first and foremost for the compiler. It has to work. Once that hurdle is cleared the next most important audience is people who will be working with the code in the future. You write it once but maintain it forever. You're job is to make that as easy as possible and following a style used by the entire group makes that easier. Insisting on doing things your way is selfish.


I don't disagree with any of these points. Where I disagree is that style differences make code less understandable or more difficult for others to work with to any meaningful degree. To me, it's roughly equivalent to stylistic differences in how people choose to communicate in written form. I'd genuinely be surprised if someone has more difficulty understanding code because a brace is on a line all by itself or not. I'd not be surprised to hear they have a preference or that they're annoyed to work with code that is not in their preferred style.


read some books about how to deal with people on the spectrum - which is what you're really asking about.

Usual acronyms of Asbergers, ADHD, ADD, PDA etc. "difficult engineers" is not something that exits in this world. There are difficult people, sometimes highly ordered jobs (like programming) attract people who like order -> many of which are on "the spectrum".

Be human, Be Kind and understand how to communicate effectively with several types of people.


You advise to be human and kind but automatically categorize "difficult people" as being on the spectrum? And no worry, some engineers don't need to be on the spectrum to be difficult. Conversely, people on the spectrum are not inherently difficult either.

But I do agree: communication is key. Craftpeople can have trouble taking the team or the business priorities into account. Being the manager, you have to take the other parties' side and talk about the non-technical problems: time to implement (= money and unavailability of the engineer), additional complexity, fragility, making changes more difficult... Convincing is always better but if you argued to no avail, you have to impose your decision – being careful not to be the asshat in the mix.


The point is that "people"'s behaviour is on a bell curve and none of us are "normal" -> some lie at the edges when they are pressured but are fine when they are relaxed. -> Some gravitate towards the center - but may slide to either side depending on specific circumstances and situations.

The true fallacy is to think there is anything "normal" at all! -> rather we have "permissable / accepted" behaviour and "impermissible / unaccepted" and a very very large grayzone in between.

And educating yourself on the edges of that bell curve gives you the tools and acceptance needed to better deal with most of the stuff happening on that curve.


> You advise to be human and kind but automatically categorize "difficult people" as being on the spectrum?

Perhaps like me they reject the people referred to are "difficult people" but believe the behaviors listed refer to people on the spectrum or otherwise neurodivergent.


exactly - all people are normal, all people are difficult, no person is normal, some people are more often challenged that others. Judging for normalcy is a fallacy


I agree that a very large portion of these instances are likely "neurotypical wants neurodivergent to be neurotypical".

That's not necessary to achieve the desired goal, but more empathy and better communication is.


In defense of simplicity: simpler code is half the time to write, half the time to explain, half the effort to debug. It's an order of magnitude more valuable than something complicated with some 2nd-order benefit.

As Henry David Thoreau (?) wrote, if I had more time I'd write a shorter letter.


I think I'll use this quote on a Confluence page I'm writing about our tech debt.


The colleagues you describe do not seem that "smart" to me.

Smart in the workplace is not just about technical brilliance and complexity.

It is at least as much about:

1. Being able to work well with others 2. Being able to take into account all constraints (which includes simplicity)

My recommendation would be to help these engineers get some coaching.


Being smart is not the end of the game, software is created by teams. You could ask them to make reverse code review so that they can enjoy each others smarteness.


To me, those last 3 points contradict the first point. The best, smartest developers I have ever worked with have consistent style (or are able to conform to the team-defined style), don't overload themselves, and prefer simplicity and elegance over complexity.


A lot of comments in this thread are assuming that the “smart” engineers aren’t self aware enough to realize what they are doing.

Let me suggest more provocatively that what we often are witnessing is power dynamics. And these people being smart know how to let this play out using code. This is probably less applicable to OPs case than let’s say a large engineering organization in a large corp.

My pragmatic suggestion in such cases is to push back where it would affect your work or growth directly and let go of the rest. Smart people are scary good at lawyering their way out of situations or tying you down in endless litigation.

There’s no “solution” to this. Power dynamics are a part of life and code isn’t immune.


I don't think it's a power thing. To me it sounds like highly introverted, obsessive, pedantic coders. I've experienced plenty of people like this in the past.


It feels to me like these people are bored. They want intellectual/academic challenge and jump at any opportunity for that challenge.

Next to the other main suggestions, perhaps these people need some sort of outlet where they can scratch this itch.


You make some very subjective statements here

> ... overly complex ...

To you, it might be overly complex. Who is to say that your assessment of "overly" is accurate? You provide a specific example that seems to prove your point, at least in on particular case.

Be careful of this, as you may be the problem here.

> Their code has no consistent style

Uh, there are tools to resolve this, so, quit the complaint. Use a lint/style app, tie it to commits, or better to the IDE, and insure everyone uses the same formatter. Get consensus from the team, don't just leave it to each individual. Who is in charger here anyway?? This is a solved problem..

> They have a big appetite for adding complexity to systems

Another "subjective" assessment. Each item should be judged by it's own merits, and your "assessment that it is complex is not the final answer.

Setup a code review system, and for any 'large scale' changes, have a code review with co-workers, peers, anyone relevant. You can even discuss a proposed code change before starting the work, or, part-way through an implementation. Challenge the team to look at the proposed change and, perhaps find alternatives (if they exist), and, in that way, get some team consensus before spending the time to build a "complex" feature.

Don't judge a feature by it's complexity "per se". Some things are complex, and for one person, a "level of complexity of say "8" on a universal scale (that does not really exist), might be a 10 for them, and a 6 for someone else.. complexity is not the same to everyone, so, don't take the "least clever" person in the room as the 'standard' for what is too-complex, that will limit your system. For "complex" systems, require a bit of extra documentation. A complex system, well described and documented, can become simpler for that "less clever" person.

A bit of management here can resolve all of the issues you describe. Don't get all judgmental, use the team, and apply some leadership.

Good luck


One of the things I like about hierarchies is that such disputes should be handled by someone higher up with coding expertise. Someone or a team who can weigh in things like long term maintenance and cost. Perhaps there are similar issues elsewhere that the proposed solution, or an alternative, could solve. There's a need for someone higher up the chain, if developers can just add disputed complexity.

I see architects as the people to go to under such circumstances. They were not always interested in small things like whitespace, but I think they should take it seriously if it's brought up.


I would urge you to avoid using loaded words like "smart". It's not that they're "too smart for their own good," it's that their priorities aren't aligned with the business's or customers' priorities. For the person who dislikes white space, they're optimizing for reading the code themselves, but there are likely to be many more people besides them who look at the code. They need to understand that the priority should be making it readable for others rather than themselves, for example.


Code is firstly a social human language for machine behavior. It's not useful if others can't reason about it, maintain it, or it contains surprises.

Wise engineers don't add complexity or try to be too clever. Simple and small is elegant. Secure engineers don't have anything to prove and create maintainable code. OTOH, paycheck-driven engineers are incurious to try new things or promote software craftsmanship.

Lack of consistency can be enforced by code style linters. Let the linters be the Bad Guy(tm). Get agreement and buy-in on these beforehand.

Separate the people from the problems: give immediate, actionable, constructive feedback privately. Use frame taking to show how their actions come across and the concerns you have... for example, who supports this code when there's an P0?

Mentors are also needed. If possible, hire or advance an "old timer" in the space who can teach some new dogs new tricks.

Whitespace... I come from Ruby land where visual alignment, proper spacing, and terseness are valued. Too many comments and too much whitespace are a distraction, just like condensing too much. In general, very small functions, good semantic naming, DRY, and few levels of indentation make code more pleasurable to read than giant god functions with duplication or excessive line length. Code that runs together without functional visual separation doesn't make it clear what's prologue assertions and setup, main work, and epilogue return.


When I read your postI can't help but read smart as "smart". You vacillate between holding their intelligence in esteem "but eventually I came to understand that he is so good at reading code..." and condescending "... I can only describe as being a little too smart for their own good"

Now the real question is do you believe you are right? Do you really(and I mean really deep down) think these people are smart. Do you think you have a better way? Do you wish they'd realize that what you are doing is best path forward?

I have seen this sort of conversation pattern in the past. In my case it was a younger programmer that wanted the team to take a different approach, but at the same time were struggling with the "what if I'm wrong?" dilemma. They didn't want to throw their weight behind a proposed change in direction because of insecurities and fear of rejection. What it came across as to the rest of the team was a person that didn't want to lead but at the same time was always finding fault. When confronted they would say things like "I'm not one of the smart ones ..."

If you really are not smart as they are then trust them and learn from them. If you think you have a better path and are committed then stand up and say "This is wrong and here is a better way". If you are right and they reject you then maybe its not the place. If they are able to demonstrate that you are wrong you should accept it and move on. If you are right and they agree then you are in the promised land.


I think one of the key tensions in this kind of scenario is individuals combination of traits massively influence the way they view the code and they're generally blind as to what the world looks like to engineers with a different combination of traits.

Just because someone has a higher IQ doesn't make them objectively better on all measures. It usually does mean they have cognitive access to things that others do not, and this can be beneficial as well as detrimental. It's seriously beneficial when they are able to come up with a simpler, more elegant solution when the rest of the team can't where that solution ratchets down the level of complexity and/or the cognitive load on the team. It's seriously detrimental when they propose solutions that do the opposite simply because they can conceive of it and it solves some problem they think exists and/or that needs solving and ratchets up complexity and increases cognitive load.

I like the example of the engineer arguing for less whitespace because he personally doesn't need it where others do, but he's unable to see the effects it would have on other people were it to be removed and how in aggregate that would likely result in a worse outcome.

There's an engineer that I work with occasionally who is like this. He loves complexity and absolutely thrives on it. It's like oxygen to him. He's very smart. He's also a 20+ year veteran, 10+ of which is with the current company. There are things which I know he is uniquely capable of producing, and in such a scenario I want what he would produce as it would be significantly better than what almost anyone else would do. However, 99 times out of 100 I want what almost anyone else would produce than what he would, as he optimizes only for himself and not the wider team. We have an upcoming overhaul of a legacy system that were both chomping at the bit to get stuck into, and I've been told to "get in line", but I'm not just going to lie down and take an attitude like that when I know what the result might be. Needless to say I think it will require being both firm and diplomatic.


Requirements are a useful tool to direct the effort of a team of engineers in a productive direction. They don't have to be set in stone from the get-go - in fact, it's better if they are updated by different people as new information about your product becomes available.

This focuses discussions about when it is worth it to spend time micro-optimizing certain aspects of the system. If there's a requirement that you must consume less than X μW while in standby - then it may make sense to accept the increased complexity.


I agree that the problem is that the company doesn't seem to use requirements to guide the daily work. It should be easy to decide whether certain work is necessary - either you have a requirement or you don't.

Without requirements, people will always leave a trail of chaos in their wake as they do whatever is fun or good for their career and resume. The only advice I have for OP is to not be the sucker who acts as janitor for the messes they leave behind.


Being super smart isn't always a plus in business. People like to hire the smartest guy in the room simply because he's the smartest guy in the room and not because he'll do the best job. One of the issues of having a super genius is that they will often find the work boring or beneath their skills so they do things that are interesting to them, like implement a complex caching system from scratch -they probably thought it would be interesting to do and since it save a few bytes they could justify the work, a good manager needs to keep this kind of worker on track or they wander off to do things that interest them more. A slightly above average engineer would simply take the requirements, look at the constraints and come up with a solution that works -it would be boring but it would work. So that's the price you pay your average employee will get the job done but they likely won't do anything that makes you step back and go wow, I would have never have thought of doing it that way that's so much better. In the end you have to ask yourself is it worth the extra effort of keeping that too smart engineer engaged and on target because every now and then his brilliance creates a huge pay off or do you want a work horse that will get the job done with little fan fair.


>It took a bit, but eventually I came to understand that he is so good at reading code that he just wants it all laid out in front of him as densely as possible. He can effectively run it in his head, as long as he can see it.

In some ways, I also benefit from this. If I am working on the same code every day, I typically have it all loaded in my head anyway. If I am coming to a codebase for the first time, or coming back to it after working on something else for a long time, it is very helpful to have as much of the code as possible fit in one screen.

That said, there are tradeoffs for sure. Whitespace is not much help for me, but clearly named variables (e.g. `area` instead of `a`) are essential. Then again, there are some short variables that are very common and clear to me in specific patterns, for example in `for i, length in enumerate(boards)` I have no problem realizing immediately that `i` is short for `index` where ever I see it in the for loop body.

Three specific pieces of advice here:

1. Use an autoformatter when you need to read code to convert it to your preferred style. Don't enforce that on the team without consensus though.

2. Everyone who can afford it should buy larger monitors. 4k 32" will fit a lot of lines of code, even if it's not quite as dense.

3. Don't stress about style consistency too hard, but do attempt to match the existing style in any given project.


> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with.

You should consider whether or not the solution is actually more complex, as in the simplest implementation is larger. Or if it's just particular in a way that you find confusing. If these engineers are significantly smarter than you, which you allude to, but I'm not presuming, then there is a chance that what they are doing isn't more complex, just confusing to you.

You can try to get at this by asking them about estimated LOC for each implementation, time estimates for each implementation, or number of concepts in each implementation. A good design process usually enumerates a few more complicated solutions, then pares back to a solution optimized for the time and resource constraints. They may not understand that, and so you should explain that complexity vs functionality is an important tradeoff. They excel at producing highly functional designs, but are bad at correctly ranking those designs when complexity is a factor.

Separately, code style discussions are usually just manifestations of OCD. That comes with the territory for certain types of engineer. Those discussions are rarely important, and that energy should be directed towards finding real flaws in the code's structure or the system's design.


I think one thing to consider is the requirements. I am guilty of overcomplicating a pretty straightforward high priority process in an embedded project. But when I asked, ok, what jitter is acceptable when driving these pins, the “product owner” (lol) just said as little as possible. Or if it was ok if the period was 75ms plus a few hundred cycles they said, well it would be better if it wasn’t. When I asked if it was ok if I used a ton of interrupt and DMA resources, they said that was fine. I was enjoying myself writing a little high precision callback and signaling framework, and exploring the fancier abilities of the micro.

Now, it worked fine, easy to work with, though not straight line c code, high quality unit tests in automation, sounds good. But really, if I was solving that problem for my own project I would have used like one interrupt, taken half the time, been much more straight forward to modify, and I can’t imagine it would have worked any worse. But I was giving management the option of good or perfect, without saying hey, when I leave, which I did, other developers are going to need to carefully read my docs and spend some time to get up to speed on the “perfect” option, and I have no reason to think the results of the good option will be measurably worse…


If you use Russ Cox's definition of software engineering, "Software engineering is what happens to programming when you add time, and other programmers.", software engineering is mostly soft skills, related to working with other people (including future you). Real skills, but not really technical skills, and things which almost no one will just have "out of the box", ie something to work at.

It sounds like these guys are really good technically, but they lack software engineering skills (using the above definition). Defining the problem in terms of brains or selfishness or empathy makes it sound like personal qualities when it's probably just the skills. If you frame the discussion around Russ Cox's definition of software engineering, you can a) get them to see the soft skills defined concretely, b) get them to see serious people (russ is a serious engineer) take it seriously and define it in a helpful way and c) talk about under the umbrella of "software engineering" and doing "good software engineering" (again, using Russ's definition of it) rather than personal qualities or technical skills.


If there are sections of code that are too complicated for everyone to safely modify then that is a failure of whoever wrote it and whoever reviewed it. At the time, they may have patted themselves on the back but they need to understand that clever != good.

It isn't clear the hierarchy or size of your team or the longterm strategy/goals of the product development. Someone on the team should be pushing back on these changes as they are being planned out or before they are getting merged in.

Ideally, you have a respected senior/staff/cto engineer that can mentor these "clever" programmers. This person needs to be able to grok all the code and see at a macro level how the whole codebase is evolving.

Re: reading code - I am the same way. I spent years writing objective-c when xcode had the best code completion out there so long names weren't an issue. Long function and variable names and tons of whitespace - it is how all of Apple's libraries were written and how the projects templates were setup ¯\_(ツ)_/¯.

Best recommendation is to adopt a strict style for your codebase and ruthlessly apply it to all new code. Linting should happen automatically. There are tools that will run the linter on just the edited files so you can adopt coding styles 1 file at a time.


> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with. The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness. But the overall system becomes a little more brittle, and a little harder to reason about, two things that are much more difficult to measure than memory and power.

I don't think you (and they) can be sure that the changes make the system objectively better. You may have a hard time measuring the downsides, but they're still here. And that may be the root of the problem. You can argue with an engineer about rate of bugs, power consumption, average time to deliver a feature. But it's hard to argue about "the system being more brittle".

One way out would be to try to have metrics on the downsides of the changes that they propose. Another would be to try to make them understand that even if something is very difficult to measure, it's their job as engineer to take it into account.

I will say this without any malice: the way you describe them, they don't appear to me as "too smart" but simply as focusing on the part of the job where the results are easily measurable.


If its more than one engineer I would say there is a very real chance that the issue is the manager.

Sometimes things need to be more complex than they first appear. Think all that pesky error checking that you totally don't need as long as everything is working perfectly for an extreme case.

If the engineers are experienced think strongly about letting the do the work as long as they are ones who will also take the pain of the complexity. Also having them explain why something is needed to the rest of the team is a good way to have everyone on board with a decision and it helps bring the rest of the team up to speed.


You've had some excellent suggestions in the comments but I have yet to see the following as a tactic to try that has worked for me.

Add a mentorship role to their responsibilities where they oversee the operational maintenance of the code they write, with one iron rule: to promote the mentees' advancement, the clever coder is not ever able to further git commit to code they wrote until the mentee commits N number of changes to a chunk of code/documentation/tests they're trying to understand. The more operational the setting, even up to and including live production support at a call center, the better.

Clever code stops delivering benefits when the overall group/organization cannot support it in live operations under contracted SLA's. Clever, immature coders invariably go through a phase where they learn there is a giant step function change between coding for themselves or a tight knit peer group of clever coders and coding for an audience. Clever, mature coders expand their tooling way beyond coding to deliver for an audience. There are ways to effectively, operationally support clever code, but those solutions aren't just implemented in code.

It didn't use to be this way when our industry was orders of magnitude smaller, but the economics of the software industry nowadays has changed the dynamic. Our industrialization phase currently favors and rewards solutions at scale maintained by organizations larger than most tight-knit clever coder teams can sustain. Such clever teams are still critical for startups or insulated projects within larger organizations, but the price tag of monetization is this type of maturation.


What I learned over time is that the business side is more important than the technical side. We are making these things to better peoples lives after all.

And business requires things to be sustainable. Profit and costs are ever present things we must all be thinking of. There is definitely a tradeoff between business and user experience many times. And the business requires code be maintainable by average developers.

One argument I found effective for the kinds of people that you are talking about is to get past the “academic” correctness of the argument and move it towards the business side. They are technically correct, after all. But they may not correct be from a business perspective.

It is important to frame it in a way that spares their egos. Most (but not all) very smart people know they are smart and it is a large part of their identity. If you challenge that in any way, they will push back aggressively.

How I have learned to frame it is that, from a business perspective, we must make the software both performative AND maintainable. And by maintainable I mean, maintainable by the average human, which they clearly are not. They are smarter than most, but for the business to live beyond them, they need to write the software in a way that an “average” person can maintain it. It can become a new challenge. How to squeak out the best performance while also writing it in a way that someone dumber than them can understand and maintain it. Another way to put it is, there are quite a few brilliant people that can write brilliant code, but only the best of the best can write brilliant code that is also understandable by normal people.

Good luck!


Um, I'd say I have both your voice and the voice of the sheep shaving engineers in my head at the same time, all the time. You have to realize, those sorts need to justify their salary. And they can't do it if everything you write is just fine. They may be incredibly smart. Most of the time they're not adding complexity because they are looking at the bigger picture; they're really just trying to remain relevant. That's not to say that their suggestions might not improve the code, it really just depends whether they have a coherent plan or if success is going to be defined as shaving some cycles while making the whole more brittle, as you say.

Likely the best people to determine the time allocation for small optimizations would be people who understand the context; but then again, ALL INPUT is food for writing better code, as long as you're not obligated to follow every idea they toss out off the arm. Sometimes you are too focused on accomplishing a task, and you miss easy things you could do.

Also, keep in mind that what may seem brittle from your perspective may work if their goal is to develop a more domain specific, specialized system, and they don't care so much about interoperability.


Ha, resonates completely with me. I think it takes time and experience to hate on complexity... and maybe also just age because your brain cache becomes worse and smaller, and you have seen enough "smart" things fail, also your own ones.

And that..

> Maybe I'm lazy, but I'd sit there and think of half a dozen other ways to do it before settling on changing the module itself.

Yeah, one aatribute of good engineers is that they are lazy in the right way ;)


I'm really puzzled about where "they're brilliant" comes from. Are you not brilliant too? If nothing else, at least brilliant at writing good code?

Their code has no consistent style? Sounds like you need a coding standard. Everybody should be using the same style, and should be using it consistently. Use tools to enforce your coding standard if you can (auto-formatters and code analysis to enforce naming standards and check spelling(one of my favorite analysis features!)).

Paragraph spacing in code? Your coding standard needs to specify that code is written for the person that follows (i.e. readability and maintainability is a primary goal). Pretty much a boilerplate clause in a coding standard. With that in hand, you have ammunition to back up an discussion about whether paragraph spacing in code improves readability. (I'm inclined to think that it very much does).

As for the rest... I worry that you may be micro-managing. The discussion about dynamic or static initialization is a totally normal and expected sort of conversation to have (without regard to whether you were right or wrong). A discussion happened. You pointed out an easier way to do it. Great. But it doesn't seem productive to me to agonize for hours over a coding decision that probably took under a minute to implement. (If you were able to initialize statically, surely it couldn't have been difficult to write equivalent dynamic initialization, and to reason about it's correctness).

A decision to cache an initialized data structure. Not really that difficult to implement; and not really that difficult to reason about. I think you just need to trust your team members to make reasoned decisions about that sort of implementation detail.


(not claiming to be smart but the appetite for complexity seemed familiar)

I used to have an appetite for adding needless complexity, and what really helped me was finding better work/life balance. For example, personal projects in the evenings/weekends are a much better output to make something super complicated and brittle and just see how it falls apart or becomes impossible to make directional changes in. Also exploring other hobbies helped satisfy curiosity in a way that I would try to in my work code. Photography is a good one with a good amount of book knowledge, ability to get deeper into the subject matter, explore historical approaches (film and antique bodies) and a lot of space for creativity.

Adopting prettier really helped me with code consistency too. I used to spend time making code nest nicely or having a hard time reading others code when it didn't adhere to a familiar syntax. Prettier just undoes all my formatting on save/commit and unifies all our repos to a common syntax so in my head I just lost perfectionist impulses to put spaces or newlines in perfectly working code files.


> - They're brilliant, I mean very smart people (in an almost academic way?)

That's good, though sometimes the "academic way" can be a problem when the aim is to build a commercial product: the engineering vs research dichotomy.

> - They have a big appetite for adding complexity to systems

That's not good. One way to influence is to promote simplicity on the grounds of testing and maintenance.

If you mandate unit tests and a minimum level of code coverage, for instance, which is useful but which developers tend to hate doing, it may nudge people into thinking about simplicity.

There's also the good practice of not doing more than currently necessary.

At some point it's down the the person of authority to accept or reject change proposals and to promote/enforce good practices.

> - They also have a big appetite for adding work to their own plates

That's good as long as they can consistently deliver and they don't overwhelm themselves .

> - Their code has no consistent style

That's usually sorted by having a formally described (in a document) coding style and conducting code reviews. People will quickly closely follow the prescribed style in only just to avoid having their code rejected in code review on style grounds.


'A hacker is someone who enjoys playful cleverness'.

That's about it. Unfortunately, they can't just play their toys and get payed for that. Or can they? Well, at least not where they're currently employed.

Also how old are they? For how long they think they'll be able to retain such mental abilities and motivation?

What about other aspects of their lives? Friends? Children? Sports? Travel?

You may say these are none of your business, but I think you see what I mean. It's a matter of 'personal growth' and you as their lead can't force it. Wisdom is sometimes really painful to acquire. In this case they fall into a cognitive bias by not being aware of what others are able or unable to do. And even just recognizing that on a daily basis already has great hack value. But on the other hand that would be an achievement someone would only recognize after the fact and therefore it won't look attractive at all before the fact.

And also what does the manager you report to says about all that?


Writing complex, unreadable code takes no special talent. Writing concise, nicely structured, understandable code, but still efficient, is the harder task.


Problem: Sounds like you’re getting fixated on things that don’t matter very much.

Cause: This is a symptom of micromanagement. Smart people will always come up with ways to improve anything you give them.

Solution: Lay out the entire problem and let them work on whatever part they think is the most important to the solution. Avoid confusion between solution design and problem specification.


In my experience, the smartest people write code that is almost unbelievably simple, so simple you almost don't believe it works or someone didn't think of it before.

The goal of writing code is so other people can maintain it because you won't be there forever and you can't do it yourself.

I've seen this in C++ engineers in particular. There's a certain kind of person who comes to believe that complexity is a virtue. In a way they're bored and they alleviate that boredom by finding the dark corners of the standard and insist on using those features. It's also a way of demonstrating how smart and knowledgeable they are.

It's also a defensive measure as it makes it really hard to replace such people.

If such people are already running the aslyum (so to speak), you're probably going to have a bad time because (IME) they're just not receptive to the people argument or they dismiss it with a quip about anyone should be able to recite the C++ standard by heart.

The best yo ucan do is constantly ask questions like "do we need this?" and "is this the quickest way to do this?"


> It took a bit, but eventually I came to understand that he is so good at reading code that he just wants it all laid out in front of him as densely as possible. He can effectively run it in his head, as long as he can see it.

I've seen this a lot in people with huge working memories. Pointing out that I (and most others) simply can not pile in all of that information at once typically leads to a solution.


> But the overall system becomes a little more brittle, and a little harder to reason about

> minimize the amount of brainpower I needed to understand my code

> weighing it against the larger system.

If you haven't try converting these items into something more measurable, and put these problems in front of the smart engineer and let these be their problem?

Sort of delegating these stuffs as their problem too instead of taking it all your own.


Could these be described by KPIs?

Time per line, for other team members to have read and understood my code changes :-)

Amount of brain electricity and coffee consumed per line read?


No :v

I might have picked the wrong word "measurable". It's better to stay away from ultra-narrow measurement. "When a measure becomes a target, it ceases to be a good measure" Instead, put the phenomenon in their head. Make it their responsibility. Point out the impact of readability to the team velocity.

Or maybe, examine if the introduced complexity is actually incidental and not essential. IF it is essential, it makes more sense to upskill the rest of the team. Hold sharing session to hear everyone's thought. Hear what the smart guy thought about the code. Sometimes, what someone need to unlock a heap of more horse power forever is just a little nudge that makes them click. Create team conventions for making things easier for everyone, e.g. indirection through naming in which you need to pay a bit in performance.


I hear you on this, I've worked with folks who have made what should be relatively simple code both undecipherable and unmaintainable, all in the name of some spurious benefit but really just to try out some approach they've read.

My response would be to ask them to support some other code for a while, turn the tables somewhat and argue against any whacky changes in the name of maintainability.


> In a past role, I got into a debate about code style with the smartest person I've ever worked with.

As other said, maybe these guys aren't as smart as you think they are and they may be difficult to work with. It's hard to say with a couple of anecdotes. Also, they could be good at some things, and yet take bad decisions for other things.

If I were you, I'd try to make my point in a non-conflictual way with rationale arguments and listen to their point of view. Eventually, follow what they say if they're strongly opinionated and have more seniority than you, for the sake of moving forward and avoiding conflict over minor things.

If you really think the issue is important, you can also try to open up the discussion to more people in the company. Like write a proposal to enforce better coding style through the use of code formater (or give a short talk), gather feedback and try to reach a consensus.

But I think I'd let it go. Eventually, you will switch team or company, work with different people, and also be better a determining who you want to work with or not.


First, as a former CTO thank you for caring about your work and the long term/downstream effects of design considerations. It's impossible to build anything actually useful without exactly the approach you're taking.

It also takes courage to ask this kind of a question and it's clear that you are a rare engineering leader who cares deeply about your coworkers and your output. You probably don't hear thank you enough, so I'll say it again: Thank you for caring.

To your question:

My answer is, always go back to the holistic goal of the system and make sure that the team is aligned - otherwise you fall victim to micromanagement. At the end of the day your job is to expertly balance long and short term goals of the business against long and short term goals of the team. If there are fundamental misalignment between these then nothing you can do will solve the problem it will just come up in different ways and you'll play whack-a-mole forever.

What strikes me about your situation is that your coworker seems to have developed a "knock the task out as quickly as possible" routine, and is really good at delivering quality features quickly. Of course, the industry has done literally everything it can do force engineers into this myopic approach (I won't rant as to why but suffice to say I think it's based on greed) and doesn't make your life any easier.

I don't know what your situation is, but I think finding a way to slow down so that nobody feels rushed and have been actively provided dedicated time for higher abstraction design and architecture. People joke about "Architects" - but this example is precisely why those jobs are critical in many cases. It's your job as the engineering leader to do that architecture work.

Best of luck and keep up the great work!


The issue is these people are bored, they want challenges, and they want to try and build the things they dream up because they're curious to see if they work as expected.

Give them a library or tool to build that the team can use, something with a clear boundary from the rest of the code base, and that has a fairly limited domain/scope so it won't need constant maintenance.


Talk to them about these issues? I think eventually these sorts of people figure out that they have a better time if they use their smarts to understand the problems and design things that are as simple as possible. Ideally you could find someone who is later in their career and has made these mistakes already, but I'm not sure you can prevent people from doing silly things until they are personally burned by doing silly things.

Taking the caching scheme as an example, even if it's difficult to reject caching in general, I think you could successfully push for the scheme to be simpler and code complexity forced on users of the cache to be smaller (the latter you can probably get down to 0).

> In a past role, I got into a debate about code style with the smartest person I've ever worked with. It boiled down to me advocating for more whitespace in his code and him arguing that adding whitespace made the code harder to read. It took a bit, but eventually I came to understand that he is so good at reading code that he just wants it all laid out in front of him as densely as possible. He can effectively run it in his head, as long as he can see it.

> That was baffling to me, I walked away thinking that I must be pretty bad at reading code. I use a very consistent style with long variable and function names, I keep my solutions as simple as I can, and I use whitespace generously to provide visual cues about the code's structure. All of this is to minimize the amount of brainpower I needed to understand my code, so I can put that energy toward thinking about the problem itself.

Denser code favors people who cultivate expertise. Less dense and more regular code favors people who receive a single ticket to edit a feature they have never seen before. Almost all orgs enforce the latter style. It's worth considering what sort of thing the thing is, and what sort of people will work on it.


Rejoice, as you have issues that are really easy to improve upon.

First of all, don’t ever argue about solutions with your peers (e.g. whitespaces), and dive deep (Can you imagine that it is hard for others to read your code? Have you tried reading your own code that you have not touched for 5-10 years? Etc.). From what I hear, you might just ask the question to yourself before you confront your coworkers. And then ask Why at least several more times for every answer.

You also are very close to understanding the core issues: It typically matters to understand the business problem and find the simplest solution, with the least effort to resolve any problems.

You might get good mileage out of studying domain driven design at this point in your path.


The issue isn't smarts, it's arrogance and the only way to tame that is to make it clear the impact of their arrogance.

Demonstrate the complexity and its cost and why it isn't smart.

Show why a lack of consistency isn't smart.

Show why adding work that doesn't align with goals isn't smart.

Show, don't tell. Be the change you want to see in the world. Educate. Encourage humbleness


At some point in their career the problem they're trying to solve will overwhelm even their own abilities - it just hasn't happened yet, but when it does, they'll be in for a reckoning.

All of the tooling, and processes, documentation, and code modularization that it takes us mortals to build complex things - this guy likely does in his sleep without it, until there's a problem he'll face where he can't anymore. He hasn't learned the curse of the gifted. You might have met this guy in high school - didn't need to study for his tests, aced most of his classes, then he specialized in college and ran into trouble because he never bothered to build such rigor into what he set out to achieve, it came naturally - and the longer that problem occurs the harder it becomes to learn the kinds of things that us mere mortals require.

My advice, if you can't manage him in house, manage him out


It sounds like there might be a larger project management issue within your team, though it’s hard to tell from a single example. Features should solve business problems and should come from your clients and/or users and not from engineers. Are your users complaining about your static solution? If not, then why change it? Engineers should work on things that will add value to the business. Arbitrary performance improvements and code rewrites that don’t solve any business issues should be rejected by your project manager.

My suggestion would be to bring this to the attention of your PM. If that fails, then focus on picking up tasks of high value and visibility. Let the “smart” engineers do code rewrites or performance improvements. You’ll have a lot more to show on your resume, feel a greater sense of accomplishment in your work, and will have a greater chance of getting noticed as a star on your team.


In my experience, it takes a lot of will and brainpower to understand complex codebases and issues and find solutions, and sometimes the energy is just not there. When it happens, it feels better to do some overengineered, objectively helpful and poorly thought work than doing nothing at all. It's some kind of sprint vs a run.


Your description overlaps quite a bit with someone who has ADHD Inattentive Type. I suggest checking out https://www.amazon.com/ADHD-2-0-Essential-Strategies-Distrac...


I worked with a very strong manager who would just fire this type of person after six months. He would give them a good chance to fit in, but if they insisted on arguing, they were gone. It was really good for the rest of the team. We produced simple, reliable, high quality code. It was an enjoyable, low stress environment.


I'm not in embedded, but my reasoning is simple. I'm keeping system as simple as possible and I put veto to things that I find unnecessarily complex. I don't think that smart person will want to make a system more complex. The genius makes stuff as simple as possible (but not simpler). I'm not genius but I strive to follow this direction. And if someone follow the complexity direction, I consider him not so smart yet.

As to whitespaces. It does not matter and not worth arguing. Either way works. You need to accept that some people might write code differently from you and that's OK. It does not make that code inherently complex. Of course there should be code style and in my opinion the more strict code style - the better, but it still will not cover everything, there's still some freedom and peers should respect that freedom and not push their own view of beatiful.


> As a tech lead I see my primary contribution as saying “no” to features that co-workers think are important but can’t justify. The real trick is knowing when a new feature adds linear complexity (its own weight only) or geometric complexity (interacts with other features). Both should be avoided, but the latter requires extra-convincing justification.

https://www.teamten.com/lawrence/writings/norris-numbers.htm...

The main tool is to come up with a neutral system for measuring the complexity of a proposal, and then use benign punitive measures like "whoever broke the build has to bring donuts in the morning" to reinforce that the team favors boring stability over fragile complexity.


I had this issue before -- I spent a long time trying to figure out what my brain told me was 'clever' code. For me it was 2 things:

1. Code that takes advantage of a constraint in an unexpected way (if you know the input will always be 'a' or 'b', you can write 'if not a:' and do things that assume 'b')

2. Code that allows for reuse in an unexpected way (you know these because the explanation in code review is 'in case we switch to system-X, we won't need to re-do this part')

Both of these are really cool in an academic setting because they're bonuses. They're like plot twists, only with code. However, in the real world, these are both pretty bad.

1 is bad because you generally don't know what constraints are 'fixed' and what aren't in your business. 'not a' might mean 'b' today but might not in two months. Your best bet is to make very clear easy-to-understand, easy-to-predict code so when you do learn new constraints you can quickly fix or extend the code.

2 is bad because it's usually premature optimization. Honestly think back to how many times you or someone you know has added code in this way, adding an abstraction layer somewhere or adding complexity because it will allow for extendability later, and think back to how often the code had to be extended in the way predicted. Usually this seemingly clever piece of code ends up being a weird extra step you always have to remember later ("oh, then we convert it into an array of strings and back into ints")

So I would say you should look at the applications you're building and think about what 'smart' code really looks like in your day-to-day and if the people you're talking to are creating such code. I'd argue they aren't, and one of the problems is that part of you believes they are, so you're having trouble articulating why they should stop and why it's harmful.


A couple strategies come to mind, but may need a bit of tweaking for your specific situation.

Code style: mostly an already lost cause debate between two coders. Pick a third party style that you both can agree to use and agree never to add special rules. Just don’t. Use auto formatter. Debate settled, and both (all) parties will adapt to new style. Ex: in python, use ‘black’ formatter, end of story.

Extra features that make code harder to read: don’t make the problem about the coding/technical problems, make it about end user usage, business problems, and business opportunity cost. Will the end user care more about this dynamic hyper optimized code thing, or an extra feature? Can the business charge more for the extra optimization?

No matter how brilliant the code is, it’s useless if the end user doesn’t end up using it - if they don’t know how or if they just won’t really care.


You have to stop micromanaging your engineers. As a manager, you set priorities such as features, footprint, test coverage and so on. Your reports are either qualified, in which case they can make day to day decisions like caching schemes or unqualified, in which case you and them need to work for alternative arrangements. One non-micromanaging way to institute quality controls is to institute peer code reviews for check ins, whether it makes sense depends on scale of your team, big shops tend to do that. Manually tweaking whitespaces in 2023 is silly, there are plenty of automated formatting tools for everyone to reformat whatever way they like for their own comprehension.

Could be also that your team could take on a lot more work, and would reduce temptation to add unnecessary complexity or argue about small things.


I got the impression they are peers, not a manager.


Kind of aside but kind of not - while you have a throwaway account,you have described situation in extremely specific and fairly unique detail, with personal anecdotes and your opinion on people involved explicitly stated. Have you considered the risk these overly smart engineers might frequent Hacker News?


To be honest I think this comes from a lack of experience on their end. They might be technically skilled but haven't really experienced trading off complexity for performance/memory use/"elegance", etc., or weren't the ones to suffer the consequences of an overcomplicated system.

I think the more experience you have the more you appreciate that a clear, maintainable and "pretty good" system always wins in the long run over a solution that's better in some dimension but opaque and unmaintainable, unless that dimension is really business critical.

It also sounds like they're just bored to be honest, and want to implement something because it's interesting or challenging, not because it actually makes sense. Maybe the best thing is to find them an interesting project that's actually useful.


Communicate the metrics you value for long term resilience and that efficiency is not more important. Explain why, use the example of them getting into a car accident.

If you have to fire such a person you failed at communicating the relevant metrics to them. They are clearly going out of their way to optimize for something, they are simply working with an incomplete understanding of what to optimize for and what costs that incurs.

edit: Communicate it like you would communicate that the great new improvement in start-up time came at the cost of energy consumption or unit price. Its great but it missed an existential metric.

While there are people that maneuver themself into positions making themselves irreplaceable, quite a few simply have the urge to clean up and make a nicer solution. Their definition of nice is just incomplete.


> What was notable, though, was his immediate willingness to write that feature. Maybe I'm lazy, but I'd sit there and think of half a dozen other ways to do it before settling on changing the module itself.

Look, your soldiers have got to be ready to fight. Your soldiers probably need to like to fight. It may not be an inherently good quality but it is a necessary quality for someone who has it for their job.

It is the generals' job to think lazily and devise ways to avoid fighting when unnecessary and to make each fight as brutish and short as possible; and it is your job to do that with solutioning.

I get paid well to be the type of person who will spend hours investigating a possibly ephemeral, possibly nonexistent bug, and my product manager gets paid well to prevent me from doing that whenever the business has other priorities.


Speaking as a long-time lead, they're under-challenged and looking for hard problems.

I've dealt with the whitespace issue by 1) moving to clang format with Google style, and 2) getting people who want less whitespace etc to mentor more junior members of the team who can't read code that dense or quickly


Maybe give them hard problems to solve? My bet is that they are looking for recognition or excitement, or both.


Agree, when the problem is presented clearly, engineer will try to find a way around it.


Incorrect imho;

Smart engineers reduce complexity.

Smart engineers reduce their own work, unless they're looking to make an impression.

Smart engineers relate to the team and their code style, and understand the value for maintainability.

What you have are arrogant engineers, who don't yet know enough, but are attempting make you think they're smart (and may have some chops).

The true genius is the underdog who gets stuff done, massively progressing projects, without you noticing or them making waves or more work for the team.

They don't tend to get noticed and will move on if not tended. You'll notice their loss when they leave by brain drain and project velocity drop. They will have documented project's stuff for others, but others won't have the same enthusiasm to bother to learn it.


Probably the simplest and most reasonable comment in the thread.


> I work in embedded systems, so I'm generally writing C for resource-constrained systems. This sort of environment is rife with footguns, and I spend most of my time just trying to avoid those. A big part of that is keeping the things that my team controls as simple as possible, and while we are resource constrained, it's a balance.

Do you measure the balance?

I write software for drones. Power use is a very real concern and its performance must be balanced with real-world-clock performance. So I wrote some starter benchmarks and tasked the team to continue writing benchmarks against their code. When the team wants to simplify something, we also measure that against benchmarks.

We use C++ instead of C. You can still footgun yourself with C++ but it provides a lot more safety mechanisms than C.


Mentorship and management is what it'll take to get these people in line.

Sometimes smart people need to be micromanaged and others simply need very clear boundaries. Which they need is highly dependent on their personality.

For example, style guides can be used to keep code consistent and readable. The goal is to code for humans not computers. You immortalize these values into the style guide, and if the "smart" persons code doesn't align with the style guide then it doesn't get accepted.

As for the complexities, stop letting them get that far without checking in first. While it may seem quite grade school, it's time that these people submit design documents outlining their solution before they write any code. This will give you a chance to push back on complexity before it's gone too far.


My view would be to have them use their cleverness by having them work on tooling, and that the measure of success is how well it works for the rest of the team. That ties their cleverness to the team's acceptance of the usefulness of the tool. Might be a humbling experience for them.


I think I recognize the type.

It's even harder to work with these engineers if, like me, you don't have a lot of experience (or are not that smart).

Are these the type of engineers that will tell you "don't do this" when they review your PRs and then you will find "this" in all of their implementations?

It's not easy to work with them but I was hoping that with more experience I'd be able to challenge their ideas with more confidence... Now I think that will never happen..

Usually reviewing their PRs would take me at least half a day of work... Maybe even more


Those used to be called "junior engineers." You should always try to hire smart people, right? The "academic-seeming" ones are probably fairly fresh out of college.

What they're lacking that the grizzled old vets have is experience.

So is your question about how to give them experience?

Let them experiment and fail in small ways that would hurt everyone else. We learn best through failure. Give them cordoned-off pieces of things to work with. Work with them on how to plan work - what factors matter and why. Do frequent check-ins with them to see how they're approaching things and what problems they're facing. Ask lots of questions, provide advice, but don't offer too much of that advice unsolicited (because failing is a better teacher than you are). Mentor them!


Decades ago I was working on an algorithm to calculate parameters of my model based on experimental data. I was sort of getting there but the thing was slow and the results were sometimes iffy. I asked my friend whose capacity for complex math exceeded mine by at least an order of magnitude. After few tries he came up with some algo that had solved all my problems with flying colors. His code was very terse and I can't quite understand how his algo works at all. After he had explained its theory to me I realized how genius it was and that I had no chance coming with something like this on my own.

I could then "beautify" his code. Way better than trying to fuck with his mind. I am glad people like this exist. They solve problems many other people can't.


Thanks for confirming this is a type - never attend a meeting, over engineer always and often. I’ve worked with one and hated it. I think it comes down to a strong manager, or else these types run wild. If they make get promoted, causes attrition as they’re a nightmare to learn from.

Some greatest hits:

- (what I knew to be rebuild data dog from scratch but they did not as they didn’t have a background in it) in the spirit of engineering first, build on our horrible internal logging/alerting tool as the prod solution. When a license and free seats existed for DD.

- attend no meetings, bake a doc internally or side channel with teams, announce the result of both in a team meeting that’s a superset of the team work they just didn’t participate in. And do it 4 times.

- open gossip on who’s a good engineer or not


> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with. The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness.

Flatter their egos while pointing out that they're optimizing for the wrong goal. Their objective is write something that works and can be understood, managed and extended by someone dumber or less careful than they are. That will rule out some changes entirely, but if they're really smart, that can also spur them to change their designs so they still objectively improve the system while retaining clarity.


personally I hate it when some engineers try to pull some "advanced" design patterns that take almost the double mental effort to understand. I see it all the time and am confused with those kind of people, idk if they think they are cool or are "protecting" their position at a company by making knowledge silos and steeper learning curves. I mean sure you can do composition pattern on anything, but honestly unless you are using some well known framework for it, it is most probably an overkill and if new person comes in it will take him almost double the time to pick it up. Now compare that to something as simple and stupid as well structured procedural.


My take on "smart".

There is no one thing called "smart" so all of the people debating whether this guy is smart are missing the point.

People like this are "smart" in the sense that they have a beyond average capacity to keep track of complex systems in their head.

This person appears not to be "smart" in the sense of lacking the wisdom to understand what to do with the large volume of complexity they are able to hold in memory.

In my opinion, the second is much more valuable than the first for the average problem you have to solve on a project although sometimes you need people with the first type of intelligence. But these people are usually much more liability than asset.


Don't take offence, but reading this it sounds like you're about half of the problem ;)

Your team either needs to better separate areas of work, so that you don't step on each other's feet all the time and each coder has a bit more freedom of how to solve problems, or you need to sit down and agree on a number of fundamental coding style and 'architecture' rules that everybody needs to follow.

Apart from the organisational and trust issues (which I think are the main problem here), tools like clang tidy, clang format, ASAN, UBSAN, TSAN, a CI pipeline and automated profiling/benchmarking can help to bring in some more 'objectivity' into discussions.


I think it's important, if you're the smartest person on the team, to view your role as serving the team.

I try to adopt this attitude, I love creating some machinery / abstraction / tool etc to more effectively express the solution to some business problem, but I recognise that my fellow developers must be empowered by any such machinery. I spike, educate if needed, then pair to reimplement. I also try to leave a 'back door' to reversing out of a new design, to let the old way and the new way compete in their minds - which is actually better for them. If the old way wins, I might lick my 'wounds' and try something smaller/simpler.


Being easy to reason about is so important. In my experience this is somewhere Security teams often make what I consider mistakes. Although something may appear to make the system more secure, it can make it much more complex, and then troubleshooting it or changing it becomes so burdensome that people skip upgrades, use weak passwords, and a litany of other workarounds to be able to actually use the thing to do their work. You also have no visibility into where holes might be. For example by creating unique interfaces for every operation, you do separate concerns. You also ensure no one will have time to review them all. Interesting tradeoffs.


I think there's a point of intelligence where you sort of loop back into stupidity.


These numbers may be wrong in your organization so adjust them as needed.

Every feature has a maintenance cost of about 20% of the initial cost per year. If you have a team that is 100% tasked with maintaining and adding features they will halve productivity (features) in 5 years. So there is the cost of adding the feature plus the cost of maintaining the feature and then the opportunity cost of not being able to add new features.

So how much does it cost to add that feature vs the value? There may be more value in going through the code and removing these low value features than adding them but you will have to weigh that on a project by project basis.


I was just discussing something like this with my team <usual-disclaimers/>, and dropped the obligatory Knuth quote:

“The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct.” ― Donald E. Knuth, Selected Papers on Computer Science

Notice "human beings", plural; so not just the person who's writing the code.


I totally agree with you. The "smart" solutions always end up with more technical debt. I really like the following quote on this matter:

Any fool can make something complicated. It takes a genius to make it simple.


I work with some pretty smart people that build products whose names you would recognize. While some attributes ring a bell, particularly the "no consistent style" does not. If anything, the brilliant people I've worked with were too rigid on a particular style, which led to spending too much effort on premature optimization. Could be that they thrive in the mayhem but I also wouldn't rule out that they are missing the forest through the trees and solving the relatively self-contained problems they know how to because they aren't particularly good at system design.


> They have a big appetite for adding complexity to systems

For what its worth, one of the best engineers that I've ever worked with was incredible about not adding complexity to systems. I remember reading a lot of his code and always thinking "damn, that's really simple I bet I could've thought of that" – even though of course I hadn't. I think that these engineers need coaching from people who've gained a lot of experience building complex systems in complex organizations, not just complex code, and supporting them over many years.


I wish I was too smart. I'm too dumb. Most of the large projects I've worked on make me feel this way. I hate when I have to look through multiple interfaces to figure out what is actually going on.


I've seen both sides of this. Everyone's idea of a 'sufficient solution' is different. Sometimes good enough for one engineer is not good enough for another. The opposite of the engineer who adds to much complexity to try to solve it too perfectly is the engineer who has a solution that is 'simplistic' rather than just simple. The simplistic-solution engineer is content to overlook details of the problem so that it can never be 99-100% solved/automated or extended. It's like the bad kind of laziness.


This sound like complete lack of experience in software maintenance.

Ask them to handover one of their project to another teammate and let them experience why their decisions suddenly make this task much more challenging.


I specialise in helping teams with trouble (delivering, quality, etc.) I have many times met engineers that were super smart but caused more damage than they brought value because their manager had no plan how to use them effectively.

Smart engineers can be very productive but they also demand good managers that can wield them effectively.

1. Keep praising them for their smarts. Few smart engineers will stay when the praise stops.

2. Delegate responsibilities rather than tasks. Demand results. Set up clear accountability for results that are important to you. (You may want to read Crucial Accountability).

3. Let people make mistakes. This is key. You need to show them their course of action causes problems and you will achieve nothing until they understand they are responsible for the result. If they have a plan and you put your fingers on it, they will have an excuse that their original plan would work if you did not meddle in it. Smart people are extremely good at finding excuses and believing in them.

I am selective where I let people fail. If I have a good occasion, I will present my concerns, but if the engineer presses his solution anyway I will let him. I try not to make it a super critical project or anything that would cause long term detriment. Ideal occasions is just wasted time which I try to balance against gained wisdom. I also try to find things that will have rather quick resolution.

Also, I try HARD to not be smug about it.

4. Demand teamwork. Make smart people work with other people, help other people solve their problems. Make your entire team propose and discuss the solution before it gets implemented. When I managed a team that had a lot of trouble with design quality, I found that forcing people put forward and defend their proposed solutions on the forum of the team helped eliminate worst design offenders without me having to step in. Saved a ton of time on review afterwards, practically eliminated changes that had to be scrapped and improved ability to prioritise changes.

5. I can't recommend it too much. Keep praising people. Make sure it is not empty praises. People need safety to focus on their work and the best way to do it is by praising them for things they did well. Understand is that your ability to get heard when you criticise them comes directly from the amount of praise you gave to them up to this point. But do not get into habit of following praise with criticism, otherwise praise will completely lose its value as people will start expecting to get criticised and will see the praise as just a tactic to soften the blow.

I understand this is very general advice that applies pretty much to all, not just super smart engineers. But remember that everybody thinks about themselves as smart. I find it is better to create an environment where particularly smart individuals can be productive than try to make exceptions for them. I find that smart individuals can be an inspiration to the rest of the team only when they work within the same system. When they work within the system they show to others that it is possible to be successful. When you create exemptions from the rules you show the opposite -- that the only way to be successful is to be treated specially by your manager. There are few things more damaging to the team morale.


Sounds like they need a good grounded tech lead who is working with the PM to assist them in continuity, and organization.

I worked with a wizkid fellah with Aspbergers...and for the first 3 months, absolutely hated it. Then I realized there was a method to the managements madness for him, and after that I got on board. To this day I can't believe how fast that guy wrote some of the code he wrote, and how incredibly nice he was.

Being a genius isn't always better than being organized ;o)


The endless fights about whitspaces seem so ridiculous to me. The points made by both camps are entirely valid (I prefer adding whitespace to layout blocks of functionality), but it feels like this should be something that an IDE should take care of. There should be the least amount of whitespace-changes in the VCS as possible, and the IDE should present the code how the programmer wants it to see instead. Similarly, questions such as curly brace placement and whitespaces between operators could be dealt with.


That is how my company works, everything is automatically formatted before commit, there are no debates. That's how languages like Rust and Go (and JavaScript/TypeScript via Prettier) have ended up also.

Same with lints, set up a company-wide lint configuration, apply it automatically, auto fix if possible.


You manage them in the way you manage everyone else.

You should know what is expected of every employee including how they code, how they interact with others, how productive they are, what quality you expect and you hold them to it firstly in the job description, then in 1-to-1s and maybe, eventually in the exit interview.

A business is about creating benefit to the employees, the shareholders and the customers. Whether somebody is "smart" or not is irrelevant, they are either contributing or they are not.


2 words. Polar Diagrams. Write down the constraints you might want to optimise for. Size, cost of development/maintenance, complexity, you know your business (it's best that they be business related rather than purely technical). Decide on the relative importance of each. Keep dragging people back to the polar diagram. "But didn't we say that we needed to keep maintainability high?" or "didn't we say we wanted to ship right on time".


Give the smart engineer the fixed budget and behold them to it.

Calms a lot of smart engineers down but every once in a while, a shiny gem encompassing all the bells and whistle emerges.


> They have a big appetite for adding complexity to systems

Truly brilliant engineers write code and systems that look almost stupid simple, but solve truly complex problems. You want engineers who take a complex and difficult problem and turn it into a solution so stupid simple that everyone else goes “Wait, that’s it?”.

What you got on your hands is a failure of management to feed difficult problems to bored engineers. When problems are easy, engineers will make them hard to stay entertained.


College projects were full of these kinds of issues. You'd be part of a group where there's say four of you, one or two are trying to control the direction, the remaining two are looking at each other simply trying to understand what language the first two are speaking. After working for say the first iteration, everyone has a chance to prove themselves, work/responsibilities/design-input naturally shift towards or away from individuals.


Sounds like a poor team fit. These super capable people should be in a team with other similarly capable people where they can achieve the incredible velocity they need.


Make some benchmarks and tests that track the things you care about. Speed, resources, etc are easy to test for. Simplicity: how do you evaluate if complexity is unnecessary? If you think of a better solution, suggest that. Maybe do design reviews to figure out the simplest solution before they implement it. Brittleness: use modules. Give them examples of good code, have a senior engineer review Code style: linting, auto formatting


I've found the best way to deal with these types of disagreements is focussing on the requirements. You have one set of requirements in your head (code maintenance, reliability, simplicity) and they have another set in their heads (optimizing whatever it is).

If you can shift the discussion to the _why_ rather than the _what_ I think you will have a better chance of reaching some common ground. A team needs to be pulling in the same direction.


Sounds like you are dealing with what people call "brilliant jerks". One thing I have been having worked in the industry is that brilliance is a momentary thing. Once that facade is gone, only thing that you are left with is jerk.

Someone mentioned insecure asshole. I have dealt with them. Unfortunately, lot of managers fail to identify them and eliminate them. These asshole do enough to stay in the org while making the workplace toxic.


The problem is indulging them and calling them smart, make them understand that what they are doing is not smart and deterimental to the codebase and the project.


> The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness. But the overall system becomes a little more brittle, and a little harder to reason about, two things that are much more difficult to measure than memory and power.

I work with a lot of people like this, and the key is to bring them to the realization that making a system objectively more featureful or capable does not necessarily make it objectively better: simplicity has value too. One of the key attributes of an embedded system is its longevity. If they want to make something complicated and they're the only person who will ever need to debug or understand it, that's fine, they can make it as complex as they like. But if you need a bus factor greater than 1, or work with other people, they need to design it with other people using it in mind.

Any engineer can make a complicated thing to solve a complicated problem. But the mark of a great engineer is that they can make a tool to solve that complicated problem that's simple enough for anyone to use and understand. A quote that I've often appreciated is this one from Brian Kernighan (the "K" of "K&R C", as I'm sure you and your engineers recognize):

> "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

I like to look at this, substituting the "you" who has to debug the problem in the present moment with an unknown engineer 5 years in the future with a non-working thing picking up the scraps of your work from today... How much smarter and more familiar with the problem do they have to be to figure out why your code isn't working anymore? Will such a person exist?

If this is partially an ego/respect problem, as it stereotypically often is, they'll hopefully recognize that someone 2x smarter than them probably will not be available. Another frequent stereotype of these engineers is that their creative appetite prefers building to maintaining, if you force them to maintain their creations because no one else understands or can read what they did, you may be able to encourage them to document, format, and design their code in ways that they will hope will reduce the amount of time spent on support down the road.


I work in a related field (digital logic for embedded systems) and identify with the description you gave. I find it's best to do analysis on the potential benefits/drawbacks and prioritize. Over time, you get a bunch of ideas and the pet ones fall to the wayside as it's clear that there are other features you could be working on that provide better value for less effort.


Smartness is proven by one's ability in making a complex system simpler. If your engineers can't do it, they aren't really smart.


An engineer's job is to design solutions to solve problems. Difficulties with maintenance, debugging, and developing are problems. Those problems are generally a symptom from complexity.

A good solution results in fewer net problems. A good engineer delivers good solutions. Therefore a good engineer must balance complexity against the problems they set out to solve.


Those are not "too smart" engineers. Those are "too dumb" engineers, with a will to prove that they are not that dumb to the rest of the company, or themselves.

Explain them that complexity is their worst enemy.

They won't understand.

Explain them again, with more examples, real life situations where complexity wasted time, money, and even, lives.

If they keep not understanding, fire them.


Honestly there is no good way of dealing with this kind of behaviour that is politically correct in my experience. You just have to reprimand them and tell them to spend developer time on creating business value rather than pursuing their personal itches. You have to tell them thats what is expected from a senior engineer.


But that's at odds with the job description of Senior Engineer? They're supposed to be leading, showing the team better solutions, working smarter not harder etc.

The idea that they should pretend to be an ordinary engineer is strange to me.

Personal itches? The idea was, their solution was objectively better. Not a personal itch. Defensible as better for the product. Just trickier to explain or support.

You reprimand a senior engineer, you'll have no senior engineers. Just a job shop with a pile of undesigned code, boilerplate from the example book that is even more fragile, unscalable, a hundred other problems that have technical debt of their own.

Code is a sophisticated topic. To blame folks who get that and can work with it, is misplaced criticism.


I feel like we are not in alignment on what a senior engineer should do so lets first agree on that. The primary responsibility of a senior engineer is to move the business objectives forward. Code quality can be a business objective but that needs to be decided together with the business team. If that is not a business objective then the senior engineer is wasting their time and everyone else's time on it.

A solution is objectively better only if it moves the codebase forward towards the business objectives. More often that not this involves no refactoring but surgically adding features without changing or breaking any existing functionality.


That's a business person's view.

At some point a Senior Engineer is about Engineering. Leave the marketing to that department.

The idea that 'business objectives' can be meaningful in detail at the Engineering level is hopeful. Maybe in a startup with one product, and even then, everybody is guessing about what features will resonate and what the customer base is.

No, a Senior Engineer is first about competent correct performant code. That's got to be their focus. Not attending business meetings.


Haha I am as technical as it gets (Have a masters degree in engineering from a decent school, even have written my own compiler and database system) and this is the senior engineer I want to be and have in my team.

The engineers you are describing are some of the biggest time wasters I have seen - spending months on making “engineering improvements”. One guy I met spent a year on making the perfect build system in rust lang that I could have written in cmake and bash in a week.


Not any guy I am describing.

This has reduced to cherry-picking bad examples. I think we both understand the issues by now.


Yeah okay cherry-picking an example wasnt the best idea i admit. But still the disagreement we have is between a senior engineer striving for business value vs a senior engineer striving for engineering value. I have been on both sides of this to be fair.


Do a few hundred bytes or a handful of micro-Watts matter in the product? If they don’t matter at all, you’re arguing from a stronger standpoint that the whole team should be able to contribute to the whole codebase.

If either of those does matter to the product, it’s a much more difficult call whether to sacrifice product capability for code quality.


About all I can say is good luck you are going to need it if you want to keep your sanity while dealing with someone like this. Most likely they have a "my way or the highway" mentality and will happily look down on you for insisting on adhering to the existing project standards.

I have left companies due to people like this.


The ability to avoid complexity is one of the most important skills for practical software engineering. As soon as you forget WHY you are building something, things can get crazy. You need to be able to do the calculation of work-to-value. Lots of people get this wrong (in both directions) and it is critical.


Sounds like these developers aren't very good -- they have one out of four traits of good developers. I suspect the "smart" attribute is held to such high esteem by your corporate culture that people who appear "smart" are permitted to have a long list of other glaring defects.


If they want to add complexity and put in extra work they can do it on their own pet project. Sure they want to invest the extra time now but are they also going to maintain it forever with extra effort or what happens when they leave? It seems you already have perfectly valid arguments to explain your decisions.


Try to simply talk about maintenability, and how they feel about adding more, maybe not always necessary, code in that regard.

I have to assume those engineers are not very experienced, by the way. After a few hard-to-solve bugs introduced by overly smart engineers you really start appreaciating simplicity.


You want to eliminate the possibility that its all just beauty contests in the context of internal peking order dynamics. Academic style smartness is usually not a good dimension to compete on as it tends to drift into esoteric domains that get disconnected from the objectives of the group.


In the Navy, we called it “Nuking It”. When somebody would make a problem more complex than it needed to be.

This term came from the Navy Nuclear Power School graduates, who are the best of the best in academic scores, but often lack social graces and suffer from overthinking even simple tasks.



Spiders or bees. Both invertebrates. Bees work together, spiders do not.

Teams need Bees, not Spiders.

(Edit: spider not an insect, noted)


Uh not to rain on your analogy but spiders are not insects [1].

[1]: https://www.sacnaturecenter.net/visit-us/nature-blog/ask-a-n...


Arthropod would probably be the most specific classification that bees and spiders share.


A spider is not an insect, however.


This is known-hard problem, involves building mutual trust and getting everybody aligned towards the same balance of business and engineering excellence.

The lazy solution is to bring in a consultant or tech advisor with some impressive resume and thoughtful demeanor.


https://www.youtube.com/watch?v=IWy1FBArO7c

smart people are even more vulnerable to bad ideas, because they can convince themselves that their ideas are good, in extremely rational and rhetorical way


Lot of smart people are convinced they can think a bad idea into a good one.


This is an issue that seems to often crop up in Linux mailing lists. You may look at how Linus Torvalds handles it.

You said "productive and friendly" way though, and I'm afraid Linus will usually fulfill only one of the two :) He makes some very sound arguments though.


Challenge them by describing a production path that solves both of your problems being business savvy AND being engineering savvy. As Knuth said, the computer doesn’t care if it is spaghetti code—but you won’t accumulate capital with Knuth’s bug rewards, either.


You're working too hard. Just make a linter or auto formater do the work. Agree on the rules. If the rule doesn't exist don't comment on style. You can make/debate new rules but don't mix it into code reviews - separate problems.



one generous approach may be to steer that appetite for complexity towards tooling rather than the actual system.

it's not such a problem if they over-engineer too-smart tools to help maintain and administer your carefully managed, just-smart-enough system. When they move on, a 'normal' replacement doesn't necessarily have to reason about the complexity: if the tools break, or are too hard to understand, the next dev can revert to simpler tools.

it's great to keep really smart people around, but it's also great to have a business that is insulated from risk by minimising unnecessary complexity and engineering for maintainability.

if they're too smart to realise that, maybe they'd be happier elsewhere.


The problem isn't that your engineers are too smart, it's that they aren't smart enough. It reminds me of the church of the subgenius: a church for those who aren't quite smart enough to be genius level and know it.

Basically, they're bored. And they make their job more interesting by making things unnecessarily harder.

I mean, when you think about it embedded is pretty simple; there aren't a lot of new challenges. You bring up a new board, it's like an old board but different. Port a new package over, big whoop.

What you need to do is give them a real challenge...then all the other stuff will become super simplified because they want to spend their brainpower on meat. What about a way to retarget your code? Or do some super cool thing, like a HAL (you said you were embedded, and a HAL is something that usually would benefit any embedded team)? What about porting WASM to your platform(s) and retargeting your stuff at it? Or doing an LLVM-based runtime for your embedded stuff?

TL;DR: Your company hired a bunch of smart guys, and they want to do smart things. Code maintenance isn't a smart thing, it's boring. Give them something smart to do that'll help your company long term, something really hard.


Oddly enough, I just wrote a somewhat whimsical note on precisely this situation. http://blog.karliner.net/posts/probletronics/


Are they young? This reeks of inexperience and hubris. Let them make a mistake and stay up a few nights in a row to fix it. The only way people like this will learn is when the consequences of their decisions affects their quality of life.


except it's everyone else that has to maintain the code that pays the price


That sounds like an organizational anti-pattern.


You are the smarter one in this story. As soon as you understand that, you'll know how to find your place and ignore them.


This may happen in every field, but front-end suffered this enormously for the last ~20 years! (JavaScript fatigue, anyone?)

I think there is a spectrum with two opposite poles: The ones that think that a complex problem requires a complex solution and those who try to solve complex problems with elegant solutions.

The first group transfers all the complexity directly to the solution, the latter tries to eradicate complexity by dumbing down the problem first.

I found that engineers tend to be in the first group. Designers (especially UX's) tend to form the second group. The fact that there is a "Complexity Reduction"[0] trend in UX may be both a cause or an effect of this (I'm not really sure).

Another UI example.

This is a popular software made by the first group: https://www.bulkrenameutility.co.uk/assets/img-bru/mainscr.p...

This is the same problem solved by the second group: https://cdn.osxdaily.com/wp-content/uploads/2015/05/choose-b...

This may be also explicative: https://xkcd.com/538/

[0]: https://medium.com/slate-teams/complexion-reduction-a-new-tr...


I have been an engineer like this. What I see is a developer who is insufficiently challenged or uninterested by the straight-forward solution. The difficulty-level and/or amount of work is too low, so they have the capacity to propose and implement a more complex one that's interesting.

Phrasing as "too smart" is curious. Do you mean too smart for their own (or product/company's) good or for you to manage? I think it really means that they're not productively directed. Including them in some longer term problems/discussions might give them context on how to weigh things better.

I think the idea of "unnecessary complexity" can be avoided two ways: 1. in terms of opportunity cost, if they don't have anything better to work on then it's hard to refute this way, and 2. in terms of maintainability or added risk--they won't see it as a problem but it would be for other team members.

I don't know what your development/shipping process is like but one good way to level your team is to adopt pair programming and rotate pairings e.g. weekly/biweekly depending on the nature of the work. This settles the dev culture/conventions better than anything else I've experienced. It also means that knowledge gets shared and generally more confident that you have 2x coverage.

I agree with comment about allowing some "probably-unnecessary complexity" as your assessment may not always be correct and even if it were allowing it sometimes adds meaning to the times you don't. It also avoids demoralizing their enthusiasm.

Another good idea proposed is about side-projects. But I would say have one for them at the company rather than a personal project. Something that could benefit the product and team to improve a process or validate correctness, completeness, etc. The great thing about this is that it's out-of-band--it runs outside of the shipped product. I've often written complex generators or validators where the results end up in the product but not the complex thing itself.

As for the whitespace thing, I advocate for the amount of space to be proportional to how important a piece is to the overall processing. Making each thing as easy to read as possible by adding whitespace detracts from understanding the whole. Any common idioms can be written as densely as possible with no loss of comprehension. I find jr devs putting one argument per line far too often "for readability"--beware consistency for its own sake. Length of a var name should be roughly proportional to how distantly it's used.


I’ve worked with many of these types and I no longer feel that engineers that meet this criteria are smarter - programming is 90% a communication problem and I’ve found that these personalities often have sub-par communication.


Code is read many more times than it is written, so optimize for readability.

Ask the engineers if they want the company to grow. If they do, that will necessitate hiring new people. Write code with those completely new people in mind.


I know exactly how you feel. I'm currently learning an embedded system to take over from a genius engineer who wrote half the code in assembly and uses lots of goto statements, because they take fewer cycles to execute.


You can always set up the editor to hide excess whitespace, but it's harder to tell the editor to insert whitespace at semantically meaningful places. So you should do it your way, as it makes it easier for more people.


It kinda sounds like your team doesn't have enough work to do? And those engineers need side projects or toys to work on.

They're willing to do those things because it's fun, rather than because it solves a problem


I am not a great fan of agile and people that argue strongly for it. I like tools that encourage critical thinking and design development docs, well defined prototypes, and working on customer requirements docs. I think Agile in it's most naive form makes those things harder than they need to be, but of course you can fit good practice into almost any framework.

I am though a big fan of frequent checkpoints, and checking in with the 'big engineering' / 'refactor everything' people before they get too carried away with code only tangentially related to the business case. Agile provides a really good 'excuse' to do the check in, demo code, and a time to reflect if what the developer has is good enough to hit the aforementioned customer requirements.


> - They have a big appetite for adding complexity to systems

This is a bad thing and will lead to it being unmaintainable. Good engineers make simple systems.

> - Their code has no consistent style

Weird. They should have consistent style if possible.


I've worked with plenty of these people in the past, and I've mostly abandoned hope for them.

Most of these issues stem of from a lack of understanding in the importance of designing a system that is simple consistent, where the least possible context is required to work with it, that is robust to refactoring and debugging, that other can work with as well, etc.

Unless they're actively trying to improve themselves with the criteria you dictate, it'll be an endless battle to get good output from them -- the management equivalent of the relationship cliché "They're damaged but I can change them".

My only approach now is to isolate them in discardable islands of code or firing them to improve team unity. Only keep if young and really willing to change and stick around.


Or fire you and hire more of them? ;P


I'm just giving my personal experience. Productivity and my overall wellbeing really got better when I got rid of developers that try to write "smart" code.


Me too. I was just alluding to the fact that when people are very different they tend to see each other as flawed. But when you strip away the defense mechanisms and look at it from the outside it’s rarely so clear cut. Maybe the people you are talking about could do your job and everybody else’s if you would just leave? ;) I’ve seen several examples where that was the case.


Your team lacks a consistent and inspiring vision.

That's it.

When smart people have a challenging goal to reach for, they reach for it together.

When they don't, they turn inward and muddle around in complexity for the sake of the challenge.


this is their job to be this way. this is how they got to the skills they have.

Only thing you can do is accept it, they are not going to change. Nobody does, people get lazy with age and experience:)

Simple thing which worked in my companies is saying: <Hey this is cool, though we have another thing in the priority right now, can you hop on it and we can discuss your complexed system after it> and this <after> never came, because usually it is intentional idea to write something complex.


There are many flavors of "smart engineer". But I think the one you're describing is the sociopathic one.

The key problem here is the lack of empathy — to users, to fellow developers, to the company goals, to the business. They basically don't care about anyone and tend to look down on others.

Those are the kind of people who would kill anyone who points out their "smart" solution is just an overengineered piece of crap in real life.

In my perspective those are not smart at all, they'd better focus on some academic research and not come close to any user facing products.

And I don't see any simple way to change this attitude, it's something deeply rooted in personality.

Of course there are other types of smart engineers who just didn't have a good example or haven't thought about caring for other factors in software engineering beyond pure CS, then it may help just being straightforward with them and find a "good" smarter developer as a role model.


These are not good engineers. Engineering is figuring things out, not boasting about abstracted ways to their self-made issues.

Come work with us. I think you'll be more happy. julien _at_ serpapi.com.


If they are adding complexity, thy aren't as smart as thy think they are. Thy are writing shit difficult to maintain software. Try explaining that to them in a nicer way than I described.


There is not such person as "too smart engineer". Picking too much on their plate may be compensated by positive reinforcement when the task is complete. Adding too much complexity to systems suggests that they are not smart enough to understand it makes extra difficulties for no gain.

Inconsistent style suggests they did not learn that most of the coding is about reading the code after it was written. Possibly they quickly write and copy&paste code, and do not need to debug it since it "worked once".

If they tell something others can hardly understand, and they are unable to explain it, then your engineers need to learn proper writing and explaining skills.

All in all, you probably need smarter engineers to manage the team.


There is no such thing as "too smart". what you are describing is too inexperienced, overconfident and sloppy. You need a manager or senior engineer who can help them improve.


>That was baffling to me, I walked away thinking that I must be pretty bad at reading code. In my experience, what constitutes readable code varies considerably between developers.


- They have a big appetite for adding complexity to systems

Treat them as potential saboteurs. Their main job is to hinder your progress to the benefit of a competitor.


That kind of developer is dangerous in a C code-base because they cannot leverage a type-system enforce proper usage of the code constructs that they create.


Make the most troublesome of them a manager of the others ;)

As for code style, don't most SCCS systems now give you the option to normalize the style upon checkin?


If the problem is that the code will be harder to understand, maybe require extensive documentation and generous commenting, all in simple ELI5 terms.


It's wisdom. They're smart, but not yet wise, as you are (at least in this context). I don't have anything helpful to add, sorry.


> Do you have any thoughts on how to work with them in a productive and friendly way?

Write them up and put them on PIP. If they do not improve, part the ways.


You can argue for KISS on the basis of productivity, maintainability, and elegance. Maybe get them to read a bit of suckless.org and suckless code.


If other people can't understand what you're doing or saying and why, you're not as smart as people might think you are.


What you are describing is a smart, but very junior engineer. As smart engineers gain experience they stop doing this sort of thing.


I'd say give them some not so important projects to satisfy their appetite for complexity and keep them from critical ones.


Rotate them periodically between each other's code. Consensus on the value of simplicity should follow after a few rounds.


Didn't you just describe a 10x developer?


Correctly managed many of them can be (in my experience). But it’s often psychologically painful for the “socially focused” to allow them that role.

Sometimes it’s just that they are too smart for the product so to speak, and all these issues are just symptoms of that.


I think the question was a joke.


I’m sure it was. But that’s my answer regardless. ;)


I still have nightmares about the levels of unnecessary complexity I’ve introduced at jobs over the years.


It seems the people you describe lack empathy for their fellow developers. I would let them go...


At least in the Go community we have much less debate around whitespace in code because gofmt.


These type of people are the worst. They are likely just building in their own job security.


what you think is 'as simple as possible' may not be the same as for them. But if they are truly adding more complexity than needed then they are not 'too smart'. that's just stupid. and you should fire them.


Sounds like they’re actually too dumb. It’s a bad sign you haven’t realized this.


You don't have smart engineers. You have bad or inexperienced engineers.


Why not just fire people you dont like? People do it all the time in America.


Could it be amphetamine use?


Could you maybe use their energy for something else? Try to refocus them by giving them other "important" stuff to work on?

Aret hey competitive? Can you maybe set out daily, weekly and/or monthly goals for them to reach (on tasks you need them to do). If they are that good and they do it all in an houre, cool, let them be free and watch Netflix or something xD

As long as the work is done (which is your goal) all is well...

It's hard to give advice since it is probably one of those "you have to be there to understand it completely", but hopefully some of this jibber-jabber helps.

But at the end of day if they're not a good fit for the work you need them to do, maybe they need to go. Maybe they'll find something their suites them better and maybe you can find people that suit you better.

Long term, everyone is happier.

If you are actively trying to find solutions to improve productivity and nothing works, maybe it's not you, it's them.

If there are still things you haven't tried, try and see what happens.


this thread is full of clueless middle managers or middle managers who are managing more people than they can handle.

those too smart folks are actually dumb in how to navigate corporate and deal with middle managers.

clueless middle managers only understand feature delivery. they have zero understanding of maintainability, stability and security.

those engineers probably fixed tons of code smells that would completely halt business either by breaking or allowing malicious actors to take over.

but they are not smart on how to communicate that work. now the middle manager only see them when they start to work on small refactors which are actually their way to wind down all the extra work they already contributed and was not accounted by anyone.


"Independent coder" vs. "team-player coder"


What role do you play in your current team? Are your teammate relatively junior (writing one liner smart code does appear common in junior engineers in my experience)? Can you set the tone on what is defined as good behaviour/good engineering? The other side is also frowned upon sometime - making glue code that just works. Do you have a yardstick to measure team's success? Does the team's behaviour align with what the product/company set out to achieve? At the end of the day, all style works, at the end of the day it is about making product that's useful within a reasonable time frame

Obligatory mention https://xkcd.com/974/


the result of leetcode interviews… hiring the wrong type of “smart” engineers


> When an engineer like this proposes something that adds unnecessary complexity, it's usually hard to argue with.

Don't argue for something, ask questions that point to the pros and cons. Eg, "do you think we might be over complicating this? I wouldn't want to add complexity unnecessarily - or do you think `x` is necessary?"

You might need to ask a few questions like this, but if you're right and ask the right questions people will tend to see the error in their thinking themselves and argue your case for you. And if not, well, maybe you are wrong. Or maybe it's just nuanced and there is no clear right or wrong answer.

I find intelligent engineers have an ability to write much more elegant solutions, but also have a larger capacity for complexity. So while they can build great solutions they're often more comfortable with complexity and will sometimes simplify things less.

I think my strength as a developer is that working memory is absolutely terrible, but otherwise I think I'm fairly intelligent. So while I can write and understand complex code, I find I'm naturally inclined to find simple ways to design and structure my code otherwise I can get quickly overwhelmed if too much is going on at once.

Something I try to do is package pieces of logic into lots of very simple services or modules - this way I'm either dealing with multiple parts at a high level or a single part at a low level. I guess some would argue this is just how to write good code, but for me I literally have to do this or my brain stops functioning. I guess my point is that there are ways that complexity can be abstracted away, so unless the extra functionality is truly unnecessary, then perhaps the solution here is just to spend some time on improving the structure of the code?

> In a past role, I got into a debate about code style with the smartest person I've ever worked with. It boiled down to me advocating for more whitespace in his code and him arguing that adding whitespace made the code harder to read. It took a bit, but eventually I came to understand that he is so good at reading code that he just wants it all laid out in front of him as densely as possible. He can effectively run it in his head, as long as he can see it.

I think this is a you problem personally. I actually struggle to understand why someone would even get into a debate about something like this. As a developer you need to have some level of flexibility in how you work. Every place I work has different coding standards, tooling and ways of working. And while these things are worth discussing as team from time, you have to be understanding that you're just one person on a team with your own personal preferences. If you can't adopt other ways of working then you're never going to work well in a team.

And to be clear, I'm not saying you have to like code with less whitespace, I'm saying it shouldn't be such a big deal that you're getting into debates with individual developers about it. If you're that bothered about it this would be something I'd probably raise in a group chat - "hey guys, just wanted to get your thoughts on whitespace - do you think we should be adding more or are you happy with how things are?"

Whatever the answer is though I don't think it's being combative or argumentative. I think you need to find a better way to resolve differences of opinion (ask questions, listen more, seek to understand) or find a way to manage the complexity you're facing - either independently, or preferably as a team.


Are you my manager? Haha


Simple systems made more complex is an indicator of developer experience, but not in the way you might think.

The Japanese have a system called Shuhari describing three stages of learning; Shu 'obey' for beginner where you follow recipes, Ha 'detach, break' where you mix recipes to mind new approaches, and Ri 'leave, separate' where you forge new paths.

I view developer growth through the lens of Shuhari as:

* Shu - Dev is using known steps from online articles, StackOverflow, etc. to accomplish tasks of limited complexity. Dev is not designing complex systems.

* Ha - Dev has learned much. They are able to design complex systems integrating multiple technologies, but those systems are overly complex. That comes from the subsystems not integrating seamlessly, APIs that could be better, and a tendency for over-engineering at this stage.

* Ri - Dev has learned not just the technologies and how to design complex systems. They have also learned how to design simple systems that work together to handle even more complexity than could be handled by what they designed in Ha stage, without being over-engineered and while still being much easier to understand by less experienced devs.

Based on what you describe, the extremely smart engineers are in the early stages of Ha; some of their practices are still in Shu (e.g., lack of code consistency).

Someone should have a frank conversation with them. Ask them 'At the end of the day, how do we provide value as devs?'. Make it clear you are not asking them to justify themselves, but lead them to the realization that we provide product from timely shipped working and usable product. Your value delivered increases as you increase how timely you ship, how well your code works, and how usable your product is.

But, to quote Admiral Akbar, 'It's a trap'. Because the conversation shouldn't end there. Then ask them, 'Which one is better to increase?'. They will likely jump on how well your code works. Lead them to the understanding that the importance of each is a balance.

* Well working code that is easily usable is useless if it ships a year after your competitors, unless your competitor's code works so badly and is so hard to use that it makes up the difference (in practice, it usually doesn't - people prefer with a 60-80% solution to their pain points now, than a 90% solution in a year).

* Timely shipped code that works well, but is unusable by anyone outside the dev team is useless to your customers (you did hallway tests right?).

* Timely shipped code that is very usable when it works, which is not most of the time, will frustrate your users, tarnish your brand, and provide a massive opportunity to your competitors.


"Smart," can mean all sorts of things and it heavily depends on whose using the word.

It sounds like you have mismatched expectations and poor communication on the team.

> The proposed change typically does indeed make the system objectively better, and they're the one taking responsibility for doing the work and ensuring its correctness

Okay, how? If they're writing a proof or a model and using a model checker to validate their model, they are able to communicate their reasoning and teach others how to read the proof or understand the model, and it's sufficient to convince an educated person that it's correct: what's the problem?

You only have to understand the reasoning.

It sounds to me that you have differing opinions on how things should be done. Take a dozen programmers, give them a specification for a problem, and you will get a dozen different solutions. Let's assume we can verify they all implement the specification faithfully: which one is the one we should use? Which one is better?

Endless debate. It's like asking a room full of programmers which programming language should be used for a given problem.

What matters is that the code works for the intended use. It's best not to bother too much with the details unless the details matter. If you have two implementations of a specification but you prefer one because it has the right performance characteristics -- those characteristics probably matter and should be in the specification. If the performance characteristics don't matter then either solution is fine...

Another way to help solve differences in expectations and start communicating on the same level: make sure everyone knows what your shared values are. Write down your list of values (readability, performance, terseness, etc) and get everyone to do the same. Make sure to clarify what you mean by each word. The set intersection of everyone's values are likely the teams' shared values: what makes the team stronger together than any individual can achieve working alone. Use those values to set preferences for things that are "debatable" like code style or when you have implementations that are equal in terms of meeting the specification and you have a stalemate on which implementation to prefer.

> I got into a debate about code style with the smartest person I've ever worked with. It boiled down to me advocating for more whitespace in his code and him arguing that adding whitespace made the code harder to read.

This is an immense waste of time. You don't have to be "smart" to have this argument. I've seen lots of programmers of all stripes over the years debate endlessly about syntactic and stylistic things like this. Pick a style, put it in a guideline or auto-formatter, and be done with it. There are more pernicious goblins hiding in your code.


IMO smartness is just a bar you need to pass. Once you pass that bar, then things like diligence and humility become more important.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: