Apologies for being nonspecific, but I don’t know how else to describe Bob’s struggles. Bob has been on the team for over a year now, and his code is just… not okay.

To his credit, he can make something that works… but that’s not enough. His code belongs on programming horror. He’s not supposed to be my junior; I’m just the repository’s lead. I spend half my week helping him. Reviewing his pull requests takes hours because it’s always a rats nest that needs significant refactoring/simplification. I’d love to say “do better” - but this is his best.

Most recently, Bob crashed his dev environment with a getter. (A mix of nested parsing logic with Angular’s change detection = CPU crashed). It’d be impressive if it wasn’t so irritating since I’ve already had a conversation with him about proper use of getters/setters. I even demonstrated how spammy the calls can be with a console.log statement for emphasis.

I could go on, but this is enough of a rant. I don’t really know how to handle him going forward; I spend so much time helping and teaching him but he retains none of it.

Is there any hope for him? Any learning material? Advice on balancing my own sanity and workload?

  • WhatTheDuck@piefed.socialOP
    link
    fedilink
    English
    arrow-up
    1
    arrow-down
    1
    ·
    7 days ago

    I’d like to see you do better than that and I get the sense that you’d like to do better than that.

    I’m not quite sure what you mean in your first paragraph. I think it’s trying to address the gatekeeping elitism experts can have? Like “they can’t code to my expectations they’re not developers worthwhile” attitudes? I agree those types are a plague, but what I’ve said here shouldn’t be in that territory.

    We don’t know how to properly quantify what knowledge/skill gap Bob is missing… just that there is one and we’re at a loss for how to improve things. That’s why I’ve used “it” for simplicity.

    Even so, keep remembering that you’re volunteering to help Bob…

    I’m… not volunteering. 😅 “My” section of the app has the most flexibility with the work available, so he’s unofficially become my responsibility.

    It’s like I have an unfilling part-time teaching role ontop of my other responsibilities. Don’t get me wrong; I don’t mind teaching nor helping someone most days, but it’s exhausting over an extended period of time with such little progress.

    I hate seeing him drown with every task he’s given. He’s a good person who’s genuinely trying to get better.

    Regardless, thank you for the good luck and everything.

    • jbrains@sh.itjust.works
      link
      fedilink
      arrow-up
      1
      ·
      edit-2
      7 days ago

      First, thanks for clarifying your outlook on all this. Indeed, I believe we’re on the same page.

      Next, no you’re not responsible for Bob, although his output seems to be your problem right now. You might be blamed for Bob’s impact on your project, but that’s not your responsibility. I understand that your manager or someone else “up there” is trying to dump this responsibility onto you. Don’t take it.

      I mean don’t take it emotionally. You are volunteering to help Bob, perhaps even only out of rational self-interest. I watch too many programmers, especially those stepping into technical leadership, who are put in your position, judge the outcome as a failure, then judge themselves as having failed. I would like to see you avoid that trap.

      Now then, if Bob is your problem, and Bob is producing output that results in a negative overall contribution to your project, then you need to limit his output right away, then help him produce better output gradually. That’s it. There’s no magic formula. He has to learn to produce what the project leadership (I infer that’s you) deems helpful, otherwise he has to be slowed down, even stopped.

      And you can absolutely be forgiven, even completely excused, for letting Bob just sit there while you deal with the consequences of his immediate output. The bottleneck is the arrival of work into your system that will ultimately be rejected (thrown away) or changed before it can be accepted. If he has less to do, then he has more time to learn, and it matters less how slowly he learns. His priority is producing output that costs less for the project to accept. The project’s priority is reducing the cost of integrating new input.

      If there are patterns to his mistakes, then it’s easier to give him direction regarding what to learn. Let him read slowly, learn slowly, improve slowly, as long as his output improves. Give him work where quality output is less urgent. Ask him to do tasks where the output can be safely thrown away or delayed indefinitely while he tries again. And yes, reserve some your time (and energy) to help him learn (not to help him merely produce more of what he already does).

      If someone (a stakeholder, project manager…) whines that Bob’s not producing enough, then you can tell them that now it’s their turn to guide his learning. “I’m limiting the damage. I’m open to being helped here. He’s not my responsibility, but he’s my problem and I’m doing my best to help him so that he can produce more for this project. I’d be happy to learn from you how better to help him so that I can help this project.”

      I went through this with someone who was fortunately an intern (so he was leaving in a few months, anyway) and who, by the purest of accidents, was shifted to installation testing, where he became a star. It shocked all of us. Even so, we were never going to be in a position to even try that move, so we were never going to be in a position to help him shine the way circumstances accidentally did. It’s a reminder how complex these situations and environments can be and the extent to which luck plays a part.

      So… Is there something Bob should read right now to keep him busy and to give him some chance of producing better output in the near future?

      PS: If Bob is learning “too slowly”, then someone with budget responsibility needs to decide what to do with him. And if someone tries to blame you for Bob’s production, I urge you to refuse it for your own long-term mental health. “I did not put him here. I do not have the authority to put someone else here. I do not have the authority to put him someone else. I can only do what I judge best for this project with the people who are here. That’s what I’m doing. I’m open to your suggestions, but I’m not responsible for this outcome. I’m doing my best.”

      • WhatTheDuck@piefed.socialOP
        link
        fedilink
        English
        arrow-up
        1
        ·
        6 days ago

        Thank you for the time you’ve spent in your reply; it’s very well put and thought out.

        Ask him to do tasks where the output can be safely thrown away or delayed indefinitely while he tries again.

        This is a great point. He’s been given “easy” tasks with - what should be - plenty of time to finish for an upcoming release. Then we feel the pain when it’s inevitably not done in time and/or being rushed to a finish. Maybe a task that’s harder with no deadline would be less stressful for everyone.

        Is there something Bob should read right now to keep him busy and to give him some chance of producing better output in the near future?

        It’s hard to know what will help him since his struggles seem to be more generic “coding principals” vs something like “understanding Python better.” For example, he’ll do weird things like use a float instead of an int or an Enum of true/false rather than a boolean. They’re small things that make you go “But…why???” …which are challenges of their own to explain without coming off demeaning.

        I’ve given him references for Design Patterns, The Typescript Handbook, and related API references when he starts a task. Do you have any recommendations that might help him?

        …if someone tries to blame you for Bob’s production…

        Thankfully management is very reasonable, and the rest of the team are more aware now. We’re working on sharing the responsibility more.

        • jbrains@sh.itjust.works
          link
          fedilink
          arrow-up
          1
          ·
          6 days ago

          For example, he’ll do weird things like use a float instead of an int or an Enum of true/false rather than a boolean. They’re small things that make you go “But…why???” …which are challenges of their own to explain without coming off demeaning.

          Excellent! These are easy discussions if you stick to asking him to account for his thinking. If you struggle to ask “why?” without sounding demeaning, then that’s something you would probably benefit from practising. I had to.

          Moreover, these are relatively safe changes, if tedious, so you can ask him to make those changes and that will slow him down while he learns. If he persists in making literally these same decisions repeatedly, then you know you have a bigger problem to deal with, and that will have to involve people with HR decision-making authority.

          What you describe also makes me wonder whether he indeed needs to know more about Python (or whichever language he’s working in), because an Enum of True and False is structurally equivalent to a boolean and sounds like Smalltalk to me. That could signal someone both unaware of what the language offers out of the box and terrified to ask questions that might be interpreted as dumb. I’m merely trying to account for the behavior you’re describing.

          For someone in that situation, they might need discussions with a patient human more urgently than books. After that, maybe Pragmatic Programmer could be an interesting starting point. I don’t know whether there is a 2020s equivalent to it.

          Thankfully management is very reasonable, and the rest of the team are more aware now. We’re working on sharing the responsibility more.

          I’m very glad to read that, for your sake. Keep going, practise patience, remain curious about Bob, and maybe this will all merely be interesting fodder for a future conference talk.

          Peace.

          • jbrains@sh.itjust.works
            link
            fedilink
            arrow-up
            1
            ·
            2 days ago

            Another thought came to my mind that might help. It is complex and will require some rambling. I apologize in advance.

            In situations like these, I want to show compassion and reach a mutually-agreeable resolution. I want to avoid passing value judgments about the other person. My experience with that intern taught me not to frame situations like this as “They have ‘it’ or don’t have ‘it’”. Anyone can do this, but maybe some folks can’t do it efficiently or effectively enough to hold a job doing it. Instead, I prefer to assume that a mutually-agreeable resolution lies in agreeing on what we’re going to try to do starting now and what we’ll do when we worry that we won’t be able to keep our agreement. In the case of Bob, the agreement can start as simply as “You won’t use a two-value Enum, but a boolean instead”. We have to start somewhere.

            In order to real a mutually-agreeable resolution, as opposed to making a decree and expecting Bob to follow it (and punishing him when he doesn’t), I typically expect the people involved to feel like someone has tried to understand them and that they have had input into the resolution. This allows them to become “autonomously motivated”, to use the language of Self-Determination Theory. (I promise: no cult. I merely wanted to put a name to it, in case it then interested you to go read more about it.) “Controled motivation” (decree + enforcement) tend to lead to short-term compliance, which often means that they’ll fail to comply at the worst possible time (Murphy’s Law). It’s less risky to cultivate autonomous motivation. There are wide-ranging theories about how to do that, but mine include what I’ve said already in this paragraph.

            We are (typically/often/largely) not trained to listen to people, but rather to wait until it’s our turn to speak by rehearsing what we intend to say. We are (typically/often/largely) not trained to cultivate true Buy-In and Commitment (Patrick Lencioni, The Five Dysfunctions of a Team), but instead to believe in fantasies such as enforcible meritocracies where rational considerations lead us to do everything The Right Way and new people merely have to Drink the Purple Juice and get on board. I mention this because we need to practise these things. We need to practise listening until that becomes a habit. We need to practise cultivating shared ownership of ideas until it becomes a habit. We need to practise seeing contoled motivation as a last resort when the risks of short-term compliance + Murphy’s Law actually seems lower than the risk of our Bobs continuing to do the strange things they do.

            We can practise by role-playing with people we trust, so that we can become aware of when our impulses under stress clash with the behavior we’d rather engage in. Gradually, we see our impulses coming from farther off, so we can step in and choose differently, even under significant stress. This is a life-long pursuit that the general population loosely calls “(emotional) growth”. ;) But what do we do with Bob, whose way of thinking seems so alien that we can’t possibly role-play him effectively? If we can’t practise talking to Bob without risking actually talking to Bob (and falling into our old, unhelpful patterns), then what’s the next best thing?

            When in doubt, be curious.

            Yes, I know. That’s dumb, but it works. If “curious” feels too fuzzy, then be open-minded. Consider more possibilities. Challenge your assumptions about what’s right and good and sensible. Here are two principles that help:

            • The Law of Three Interpretations: keep telling yourself different stories about how Bob (or the other person) is behaving until you have three distinct stories. For now, you might have to do this as post-interaction analysis, but gradually you’ll be able to do it better and more easily in real time while the conversation with Bob is happening.
            • Ask yourself “What would have to be true for me to behave like that?”, then assume that that’s pretty close to what’s happening for Bob (or the other person). Ask questions intended to check this guess and you’ll notice yourself being more curious/open-minded.

            If you do this, then there’s a very high chance that Bob will feel safer to tell you what’s happening and you’ll find more compassion for his choices. For example, I chose an Enum because I know that having multiple booleans can be difficult to understand and lead to defects when combinations of values of True and False can be meaningless or misleading. I know that improving this design means replacing the booleans with an Enum, so I chose to jump to the Enum now in order to avoid refactoring away from the boolean later. I’m not saying that Bob is thinking this, but I’m saying that if Bob were thinking this, then I would understand and have trouble disagreeing with him. I would realize that my preference for already using a boolean is in fact merely a preference and that other people might have other preferences, and although I don’t evaluate the risks the way Bob does, if I did evaluate the risks the way Bob does, then I might find Bob’s reasoning pretty reasonable.

            That’s the benefit of curiosity and open-mindedness.

            Once you’ve understood what Bob is thinking, it becomes easier to suggest or ask for alternatives. “Yes, Bob, I get it. I genuinely don’t think the boolean in this specific case was a risky choice, but I understand your general reasoning. Here’s what I’d like you to do: assume that replacing the boolean with an Enum is not going to be a problem and let us enjoy the simplicity of the boolean in the meantime. We’ll spend a lot less energy tripping over the unexpected boolean and from the energy we save, I’m confident that we’ll be able to handle replacing boolean with Enum in the few cases where that becomes necessary. In fact, I think of that refactoring as so easy that I don’t even thinking about when I do it. (Bob might interject to tell you here that he still gets tripped up by that refactoring, which is why he prefers to avoid it. Reasonable!) If we reach a situation where we regret choosing boolean over Enum, and if we start yelling about it, then we’ll rethink out Sensible Default Choice. For now, however, I need you choose boolean over a two-value Enum. Will you please do that?”

            Now yes, that might seem like a lot of effort to resolve this issue, but it will probably require less effort the next time, then less, then less… Bob will either gradually converge closer to the conventions and preferences of the group (while occasionally asking for his own preferences to become Sensible Default Choices) or he will dig in and resist in spite of your best efforts. If he resists, then you can choose whether to try to explore that using concepts from Dale Emery’s “Resistance As a Resource” or you can get The Firing Person involved as an arbiter. Only you can choose what’s right for you in that situation when you come to it.

            OK. Rambling over. Was there anything helpful in there? I have a cold right now, so although I feel clear enough to write this, it’s possible that my brain is fuzzier than I believe. I tried. :shrug: