When I first heard about tacit knowledge and started looking into it, I thought it was the same thing as tribal knowledge. You know, those things that aren’t written down, never get explained, and you just need to know to be successful. Turns out that’s not the case. On the surface they seem similar in that in both cases you aren’t told the knowledge you’re looking for. The difference is that tacit knowledge is the kind of knowledge that can’t be explained with words (at least in an amount of time that is useful), not just something that hasn’t been explained.
One classic example is riding a bicycle. Think about it. How would you explain to someone how to ride a bike? You could tell them all about the physics of flywheels and precession, but understanding the physics won’t teach you the muscle and balance feedback you need. Comparing it to standing on one foot or slack-lining doesn’t really help either, but those are comparisons, not explanations or instructions.
The next thing I thought of was that ok, this is just experiential learning. You know, learn by doing instead of learning by rote by watching, but again, not really. I’ll be the first to admit that I’m an experiential learner. I learn best by trying and watching what happens when I interact with something. But I can learn by listening to others, or just watching them do it. Learning styles are a property of the learner, not the subject.
So what is tacit knowledge? To me, it’s the knowledge you get by doing something, then having to live with the results. In software it’s the kind of knowledge that leads to a feeling that something is the right (or wrong) design. A code or design smell. You look at it and say “that’s not right.” Then you think about it and you come up with some reasons. But the reasons come after the feeling and justify it, not precede it. And that’s what makes teaching and learning tacit knowledge so hard.
Consider the expert system (really a knowledge based system). Find a few experts, look at a bunch of their decisions, and ask them why. Keep asking why. Build a sufficiently complex tree that you can use to arrive at the same conclusions. Sounds simple. People tried it and it’s not. Take a simple case. Is that function too long? It should fit on a page. It should encapsulate a single action. It should be replaceable without changing the results. It shouldn’t have too many branches. Unless it's a complicated topic. Unless it needs that many steps. Unless the combination of possible conditions is that large. Unless there are no other functions. Unless breaking it up makes it harder to reason about.
So how do you learn tacit knowledge? It’s not just repetition. Repeating the same thing over and over again will make you faster at it, but not better, and how do you know if you’re correct anyway? So you do it and look at the results. Repetition and introspection. That helps. Now you know what you did, and you can hopefully see the flaws, but that doesn’t help you get better.
For that you need to add something else. Feedback. The completion of repetition with introspection and feedback is one of the best ways to build tacit knowledge. So how do you get that in software? Of course you have to do it. You need to write the code, or do the design. Over and over again, That’s the repetition.
You need to know if it works. You test what you’ve done, and see the results. And you change things until you get the answers you think you want. That’s the introspection.
And finally, you need to share what you’ve done and get feedback, It could be a diff/PR. It could be a design doc. It could be an architectural kata. Whatever the mechanism, you need that external feedback to make sure your biases, conscious and unconscious, don’t get in the way.