It's an unwritten rule because MLB has refused to police the game and its players down through the years. Throwing at batters is the only retaliation or policing the game they have. Believe me, I understand the philosophy of retaliation in sports, especially baseball.
The commissioner could put a stop to throwing at batters tomorrow by making the penalty so severe,
no one would throw at a batter. The penalties I'm thinking of would include automatic ejection of the pitcher, the catcher and the manager for multiple games, along with a very hefty fine for all. 5 games for everybody the first time. The penalties would then
double for (for all 3) every occurrence (and keep doubling up to 162 games) after that. The fines would top out at 1 million dollars. Ownership would not look kindly upon managers being suspended for multiple games, and not being allowed to come to the ballpark.
Those penalties (games/fines) would escalate with each successive hit batter during a 162 day calendar. Fines and penalties would carry over to the next season. Games suspensions would follow a player if he is traded. The fastest way to get a player's attention is to take money from him, and take him off the playing field.
Remember the immortal words of the late UCLA basketball coach John Wooden: "the bench is an excellent teacher". The "bench" as Wooded referred to it, was meant in a different context, but the end result is exactly the same. A suspended player or manager would not be allowed to be in the dugout during games, practice or travel with the team. Sever penalties, YES!!! But the practice of throwing 90+mph fastballs at batter's heads would stop immediately. How "fair" is it to throw at the next guy up in the lineup for an action he had nothing to do with?
Somebody goes out of the baseline with his spikes up to take out your shortstop. When this happens, if a fine and a suspension from the league would quickly follow (like the next day), that type of activity would also stop IF....the penalty were severe enough. 99% of the time, the league does nothing, so the players take matters into their own hands.
I remember Chris Sale
intentionally throwing at Bryce Harper [and hitting him] at the beginning of Harper's rookie season, for no other reason than Sale thought Harper was "too cocky", and felt Harper needed to be taught a lesson. That's BS. I lost all respect for Sale that day. Some American League pitchers are cowards. They can throw at guys all season long without fear of reprisal because they never have to bat.