Hacker News new | ask | show | jobs
by jawns 1865 days ago
I notice that the vast majority of comments here are lessons learned about office dynamics and interpersonal relationships. Which either indicates that soft skills are much more important than tech skills or that HN's mostly technical audience has had more to learn about soft skills than hard skills.

To buck the trend, I'm going to add a few "hard skills" lessons I've learned from managers.

From the best: "Every if statement is death" was an adage of one. He encouraged me to think deeper about whether conditionals were really needed, and at what place they were needed. That mindset helped me write clearer and more easily testable code.

From the worst: In code, "brilliant" solutions are like poems: they're beautiful, they're terse, and they pack a lot of meaning into each line. To mid-level engineers, they have an intoxicating appeal, because they seem like a good way to flaunt their talents. But more often than not, what is really needed is the code version of ordinary prose: straightforward, with a preference for clarity over succinctness, easy for others to understand, easy to edit, and with fewer surprises and deviations from convention than a poem. Your goal should not be to impress your code reviewer with your cleverness but to impress the person who needs to maintain your code three years from now.

5 comments

I appreciate this. I think one of the more valuable advice I was given re:conditionals is to make sure the positive path is the non-branching path. Branch your exception, let your expected path fall through.

    if ( unexpected = true )
      branch;
    do_expected_stuff
Caveat: ways to do things age. Maybe this is no longer true or even slightly advantageous, but so far it has served me.

I also prefer 20 lines of simple pedestrian code to 2 lines of clever code. I remind myself that I write for the maintainers, who do not have the benefit of my resident knowledge when they encounter the code.

I learnt this one early on and definitely still encourage it (but aware of your caveat too). But I describe it differently when I'm coaching, and I think I've used the phrase "try to get your conditionals out of the way early".

My rationale is that having done this, I'm left with a smaller combinatoric mental space to work within. Like "if the program counter has reached this point then I know for a fact that X, Y, and Z don't apply - the function would have exited early if they did". And that then means the remaining set of things I have to keep in my working memory is reduced, which makes life easier.

Is that similar to how you see this advice?

This particular use of an if statement is subset of what's called a "guard clause", and I'm also a major fan of them. Other guards include an early return for edge cases or that would make the more general path more complicated, rather than just exceptions.

https://wiki.c2.com/?GuardClause/

aren't these ill defined guards?
Favor immutability. Be intentional about where state lives. Ask what happens when you leave the happy path.

Prioritize your backlog to reduce/eliminate 2 AM pages. That's the metric you care about; not tickets, not test coverage, not logging/metrics. All those others are gameable metrics. The only thing that matters other than reducing pages are features, and you'll find that by prioritizing the former, you end up delivering faster on the latter over the long haul.

> Every if statement

... has an "else" whether it's written or not. Choose carefully whether to skip writing it, but always know it's there

I try to impress that not as much upon developers, but religiously upon folks writing requirements. Many pieces of code work just fine without the else, but the amount of bugs and rewrites due to someone either not considering "but of course it always succeeds!" or because there was an implied else scenario in their head that they just didn't bother to write down are almost innumerable.

This, so much. Every branch or decision point in either the domain model/flowchart/spec/etc or implementation should be carefully considered. This applies doubly so to error handling. Also, try to make the code paths look like or at least be recognisable by the spec. Try to keep one mental model of what happens that the team all share.
Along the lines of "hard skills" from mentors, I learned that if releasing an update from your team is 1x of difficulty, and releasing an update from another team is 1x difficulty, releasing an update that has dependencies from both teams will be 10x of difficulty, because things get exponentially more complicated once you have teams all trying to do things together.
Code like Hemingway.