The Local Minima of Suckiness
veekaybee.github.io
veekaybee.github.io
Like with research, nobody can take arithmetic and single-handedly discover calculus, number theory, and higher concepts. You're not going to discover good software development paradigms without reading about some of them. You especially can't write anything useful without using high-level libraries and working with others.
At the same time, I think intrinsic motivation significantly helps learning these concepts. To some random person, learning about "one function one purpose" could be like learning random historical dates to me. "Why can't I just copy / paste the code? Why do I need good function names?" These people would have to discipline themselves and power through learning this stuff. But to me, I didn't have to discipline myself, because for some reason I was genuinely interested in writing "clean" code and making my development more efficient. This gave me an advantage. And there are people who love writing code more than I do, so when I get tired and brain fog after a couple hours they keep writing.
I'm not them. It's better to assume we all need help and direction. Just about everyone I've ever worked with has had a beautiful insight or three. The real trick seems to be finding a process that produces good enough results that isn't so soul-crushing that it extinguishes those rare brilliant insights.
https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_g...
Academic citations work the same way: saying thank you to the people who helped builds their reputation, and is a positive-feedback cycle of growth and joy. Thank you jfoutz for humbly saying that you also need help and direction; me too.
In my experience, these two learning sources - your peers at work, and your own research - yield different type of knowledge. To show you what I mean, let's dissect an example from the article:
> Think about the difference between being able to write functions that print out to your terminal versus creating a class with methods that return text to pass to other methods that checks for sanitized inputs, and then passes it to a front-end.
This belongs to "objective level" of working with code: how to write correct and efficient code, how to build the right abstractions, how to make it work in context of a larger system, etc. This kind of knowledge is something very amenable to self-directed learning: studying books, writing code, reading code, playing around, getting a feel for handling complexity, for how thoughts map to code, and code maps to execution.
> Now imagine that that class is a function that has to be packaged to work in the cloud. And, on top of that, imagine that the function has to be version-controlled in a repo where 5-6 people are regularly merging code, pass CI/CD, and is part of a system that returns the outputs of some machine learning model with latency constraints.
This belongs to "meta level" of working with code: how to write code in business context, how to collaborate with colleagues. It's not software skills - it's business skills and people skills. Both learned best through experience on the job.
Point being, the two types of knowledge/experience are somewhat orthogonal, though they reinforce each other. You won't learn how to write good code by just interacting with your peers at work, not unless one of those peers is learning independently and applying their knowledge to raise the craftsmanship level in the shop. But then, working in a team, under time and budget pressure, introduces tradeoffs that affect the way you code, in a way you just can't reproduce on personal projects.
To sell your skills to a business, and for that business to make use of them, you really need both types of learning. Companies understand the need for learning from peers well (perhaps too well, it's becoming a pro-office argument), but I wish they also understood the need for self-directed learning better, and allocated resources accordingly. As things are right now, I feel the progress in our industry mostly rests on people who are either paid to do R&D, have time to do learning off-work, or are just learning independently at work and not telling their boss.
This has to be one of the snowballing keys to success. Soliciting and rewarding negative feedback, in a way that doesn't threaten the overall.
Works for bugs in code, also for life stuff. Being teased/mocked gives incentive and direction for positive change, so long as it doesnt send one spiralling.
For example, asking a junior for feedback as a friendly gesture and exposing him to an interesting problem. If he then takes the opportunity to one-up by explaining his naive opinions about irrelevant details, do you ignore him? He will experience it as being marginalised or "gate-kept".
The problem is that youngish guys have so much ego invested in feeling smart.
My experience so far has been the exact opposite. I have mainly been in confrontational environments, from my teen years on IRC to my work places. What I have learned is that if you say shit that are wrong, or if you try to talk without knowing your subject enough, you'll get smashed without mercy. I think this kind of atmosphere played a huge role in my development, on the positive side. If I had to intervene on a subject, I would be damn sure to know it well. If I had an issue at work, I would work hard to solve it and understand all the implications before asking for help.
Not saying that's the best environment for everyone, but it sure is for some of us.
For example, "how do I sort a list of elements in python," which sounds very easy to answer, and it is for trivial cases. The complexity lies in the nuance of the question. For example, what if the list contains strings, numbers, and dates, and they were expecting it to sort by date? What if they need descending sort, not ascending sort? What if they need this for python 3, but they found a result for python 2, and they didn't even know there was a difference?
As you approach solving harder and harder problems in your career, of course you can't just ask google once click the first result, and copy paste the top answer. You need to ask google many questions, click through random forum posts from 12 years ago, read a few books on the topic, write a patch for a legacy package, try a few things, read the documentation, collaborate with other developers, etc.
The confrontational environments you've been in - did they carry with them the risk of losing everyone's respect, or getting fired / banned from community as a punishment for trying to talk without knowing your subject enough?
I'm gonna guess no. I've been in such confrontational environments (particularly around friends and colleagues in high school and on IRC) - we'd call each other out on their bullshit and overconfidence, but even the longest IRC flame wars were always on friendly terms. Direct, sometimes very heated, but always friendly banter. Such environment is also psychologically safe (at least for those who can handle the brashness), and is arguably very efficient at leveling up everyone's skill levels.
The problem really starts when you feel at risk of being punished for being wrong - when you worry that a mistake will cost you your job, or that people are judging your code and looking for reasons to push you out come next layoff round. That's what creates a lot of perverse incentives that impede the functioning of teams and companies.
I'm with you – I want people around who can call me out when I'm wrong.
My read on what the author is saying: imagine if you or I didn't have anyone to call us when we don't know what we're talking about. Imagine if we didn't have people who would tell us that we were asking questions without doing due diligence beforehand.
That's one side of what it's like to work without anyone to give you useful feedback when you're wrong.
On the flip side, useful feedback doesn't need to be "smashing without mercy." It just needs to be direct and care about accuracy (e.g. Marilyn's review of Bill's code in the post).
. . .
> There is no apprenticeship for learning how to build Docker containers or dealing with prod outages.
Conversely, we could deduce that the way the industry works, employment in specialised IT teams is de facto apprenticeship.
I particularly appreciate the whole section about "psychological safety". It resonates with me strongly. Thinking back to all the jobs I've done, I can see a clear pattern: I started doing by best work when I reached a level of comfort around people in the company, so that I stopped worrying about being judged by my co-workers and my bosses. This process usually took a lot of time (~6-8 months) - and now I think it could've been much shorter - if I was aware of this, and if my bosses were aware of this too.
I wonder how much of the "first 6+ months of a new engineer is sunk cost of onboarding" pattern is caused by this - by employees fearing judgement and feeling they need to prove themselves.
And, I know of multiple places that were not safe places to make mistakes. It was awful, I was demoralized quickly and wrote bad code and got fired.
It makes my whole body shiver to think about places where the entire organisation would pull to make it psychologically safe. It takes real courage and thoughtfulness for those in leadership to create that kind of culture because there are so many barriers (namely awful people) who will be pulling in the other direction.
I am where I am today because of my exposure to companies/teams that embody this environment
To feel "safe" asking dumb questions, you have to accept that the answer is often an irritated "RTFM". Accept first that the worst outcome is being ignored or sneered at, then you won't be so fearful.
Beginners who ask questions usually want affirmation and some sort of "experience of being a peer" or something like it.
The safe environment that people think others are responsible for, is mostly internal in my experience.
If you learned programming by programming phones or the web, your foundations change every 36 months so your improvement lags because your knowledge decays with time.
If you learned programming on firmware, Windows classic (think Petzold), or Unix, things haven't changed in decades, so your knowledge fundamentally accumulates.
If you lack those foundations, it will of course feel like everything is new all the time, because you don’t recognise the patterns and you just see a lot of trees everywhere.
After having seen a few frameworks/platform/languages picking up a new one becomes easier.