Advice for new software devs who've read all those other advice essays
buttondown.email
buttondown.email
It's frustrating and sad to see people do that. I was myself a "Right Way Guy" at the beginning of my programming for a few years, before I learned how much depth there is in CS besides junk like best practices and code style and how to focus on the only thing that matters - working code. They are often too convinced of their rightness.
Imagine a committee commissioned to approve plans for a Nuclear Power Plant. But the committee spends all their time discussing the color of the bike shed that they want built nearby.
In your case, their focus on separate VMs for QA/Production, systemd deployments, templating system for a few strings, and an ORM for a few SQL queries, especially for a project with a limited user base (10 people) really exemplifies Bike-shedding.
They’re emphasizing minor, arguably unnecessary details rather than the core functionality or purpose of the project [2]. This usually occurs because these trivial aspects are easier to understand and discuss, especially for junior devs, which leads to increased involvement on minor details while the more meaningful parts of a project (which might be more challenging to address), are overlooked or given less attention.
IMO, a good leader knows how to strike a balance between the “Right Way” and avoiding the pitfalls of “Bike-shedding”.
[1] https://en.wikipedia.org/wiki/Law_of_triviality
[2] I would argue complete documentation of the meaningful parts of the project is not bike-shedding.
Many of those things you list really don't take too much time to do, like writing systemd units or using an ORM. But they really help when anyone needs to take a look at things in the future or someone else wants to contribute as well later on. Besides, they're easier to do when things are still fresh in the mind, and these kinds of chores rarely get done later on when a project has grown.
This being a hobby project may also be a reason why the other programmers want to do things right; they may get satisfaction and learn new things by doing it this way!
Exactly my thought. Hobby projects are great opportunities to practice those skills since, if you don't, they don't manifest.
Something I missed at first [1] was the significance of an event that happens early in the movie. They need to buy a $50 router because their existing one is broken. They have an impromptu meeting where one of the characters gives suggestions on how they could try to fix the existing router. The suggestions are all half spoken before being answered: "Did you try the ..." : "yes"; "well , how about resetting the ..." : "I tried that too". Clearly they're basically reading each other's minds because of how well they know each other and how much time they spend with each other.
But then comes the 'punchline'. One character says 'yes' to buying the new router. The other response with "I need an 'aye'". Their side business apparently has very strict rules about what words they need to use for voting on decisions. It doesn't matter that they all know each other so well that they're finishing each other's sentences. It doesn't matter that this is a $50 router. And it doesn't matter that their income from this side business is inconsequential. The rules say that they need an 'aye'.
My own theory with "Right Way Guys" is that some people have been able to find a lot of success by leveraging the knowledge that's stored in the hivemind of society. They don't really know what they're doing when you consider what's going on inside their skull. But they have successfully copied success up till now. The plus side is that they're able to inherit successful methodologies that have survived over time without having to do all the hard work themselves. The down side is that they literally don't understand when they're in a scenario where it will lead to failure. [2]
[1] - I didn't think much of this until I watched the director commentary. Where they explicitly talk about how they intentionally setup this interaction to showcase how certain characters took the rules too seriously and which ones didn't take them seriously enough.
[2] - My theory on my theory is that this is also why so many people encourage others to join in their favored cargo cult practice (be it software development or anything else). Social behaviors may or may not work, but the more people you can convince to follow them the greater the chance that when they fail catastrophically and/or fatally they're failing for someone who isn't you.
And yet my toolbox is still full of things I do because someone I respect did them, or someone I disrespect didn’t, and the outcomes were dramatic. I know the expected outcomes, I have half an idea how they actually work, I just know it’s a magic spell that gets me into or out of problems. We don’t know why asking dad for ice cream works more often than mom, but empirically it does.
There are areas dictated by human factors like errors, or overconfidence. There are areas I will sweat blood to do a mindful task to avoid a mindless one, and vice versa. And there are things I do because it improves outcomes with neurodivergent people, and sometimes neurotypical ones.
There’s a concept in chronic illness circles called spoons. It is a metaphor that acknowledges that it’s not time that’s the constrained resource, it’s energy. A wake up call that software desperately needs. When you have used all your physical or emotional energy you are “out of spoons” for the day. You can’t do anything but veg.
This is slowly being replaced in psychology circles with metaphors that are more like deck building card games, because they speak also to many other groups of non-extroverts. If you aren’t prepared for a task like calling tech support or dealing with a toxic relative, being forced to do it now burns all the other tasks you might have done cheaply today. These people want to know they have a dentist appointment or a date in two days because they need to psych themselves up. Spend energy today and tomorrow making sure they have that card available. And if there’s a cancellation, they are out all that energy and have to spend it again.
There’s a lot of this in our work too. The old joke aphorism about, “why spend a day doing something you can spend a week automating?” falls under this umbrella.
Psychological aspects are a big part of this.
My pet peeve is overzealous security trolls making IT staff use four layers of VPNs and remote access solutions with multiple glacially slow MFA authentication prompts.
I watched one guy typing into a console with a two second lag on each key press. That’s the round trip time to the Moon and back!
I felt bad every time I had to ask him to do something for me, because his shoulders would slump and he’d have this depressed look on his face as he forced himself to jump through the hoops… again.
Cultural DNA (traditions, rules, and the 'right way') encode a lot of useful experience - but environment and circumstances change. And sometimes it just picks up weird things along the way.
The article is referring to the foibles common to someone who's just had their first experience with not being a cargo cultist, i.e., getting overexcited about their first taste of real understanding. Mostly these foibles involve having somewhat cringey one-sided conversations.
I have no idea how the Primer anecdote relates to anything at all.
I'm not sure what it sounded like, but I'm pretty sure I didn't feel that way.
| decided it must mean That Type Of Guy I Don't Like.
... huh. That escalated kind of quickly.
| I have no idea how the Primer anecdote relates to anything at all.
Well, I had hoped the paragraph following the anecdote explained that, but I guess I can't win them all can I.
EDIT:
What I find super interesting is that my original comment was that there are some interesting success and failure modes associated with "Right Way Guy".
And I follow it up with a musing that social pressure to conform is a way for the social hivemind to protect adherents via statistics.
THEN one of the comments looks suspiciously like it's chiding my social disharmonious actions.
Very cool.
I've always been intrigued by how the representation of those characters instantly connected so well with my engineer-identifying brain, and little details like that must have been a big part of it. It's a neat little nuance on the idea that what bits of cargo cult a person exhibits _now_ can sometimes give insight to their current place in life, and perhaps even to their deeper character and heart.
edit: Actually, on reflection,
>THEN one of the comments looks suspiciously like it's chiding my social disharmonious actions.
I consider this extremely aggressive, rude, and to bear no relation whatsoever to anything I typed. I don't understand what causes people to talk in bad faith like that.
Smart juniors know most if not all design patterns, read Mythical man month, and so on, and... is super eager to try new technologies, languages, frameworks and is literally running around with shiny new hammers desperately looking for anything resembling nails. And then they do some stupid decisions because they don't grok the power an optimized boring old DB can bring in.
Then comes a guy like me with 20 years of experience who has seen damn well how such projects end up 5-10 years down the line with half if not most of the original team gone, and cuts half of that crap out while keeping genuine added value, because we are not running kindergarten for devs who want to have fun at all costs all the time, we work for our business who pays us and expects good, stable and relatively quick deliveries, rest are details on our side. You can't be taken seriously by business if you behave like that, no matter how good your intentions are.
IMHE bleeding edge stuff and trying new things for the sake or avoiding boredom will consistently break more down the road than it will help fixing. We incorporate technologies which whole team can grok and be proficient in, not just some bored superstar. Build your CV elsewhere if you desperately want as many technology entries as possible, there are companies like that, and good for them. IMHO these folks anyway don't stay around for too long so full added value is even questionable, the grass is always greener elsewhere, at least till they get there. Could be boring for some, I call it seasoned (yet still endless amount of stuff to learn, but that's fine this won't change till my retirement).
Documentation is crucial. I have some fairly basic <300LOC projects including a bot and a web scraper that I currently cannot run because I didn't document them. The Raspberry Pi they were running on died and I need to do....something....to fix my headless virtual framebuffer and debug some cryptic errors that do not find productive search results.
If I had containerized or, at a minimum, documented my setup steps, I would not have this problem.
And never mind that opinions on "the right way" differ. Previous poster mentioned ORM: some people think "the right way" is to never use an ORM, some think "the right way" is to always use it.
Right Way Guys will insist that your codebase will always needs to be scalable, whether it makes sense or not. You've got a B2B product that will only have a few hundred customers? Doesn't matter. It needs to be scalable. It's the Right Way.
Right Way Guys will insist that this kind of ugly module that hardly sees any changes and is basically bug-free will need to be rewritten to The Right Way once they add a minor trivial feature. It doesn't mater it works fine. It's The Right Way.
Right Way Guys make things worse. Always.
In the case of juniors: they can be taught. They're just juniors. That's okay.
In the case of seniors: good luck... I'd argue these are among the worst people you can hire.
And you really don't need to be a Right Way Guy to write a few docs or set up a staging environment.
Most of the time, just do "the simplest thing that will work" is actually quite future-proof, because when (if!) it needs changing then this is usually not too hard, because it's simple. It's usually not too tricky to make something simple more complex, and the extra costs over "make it complex from the start" should be quite low.
What I do see is people just writing bad code. "zomg this function is 5,000 lines long and nested 9 levels and I can't make head or tails of it, but somehow it magically works, kind-of, with bugs, but no one really dares to touch or refactor it because the last two times we introduced regressions and had to scramble a fix and there are no tests, and adding tests is hard and requires refactoring which we don't dare". That type of stuff. Not an hypothetical exaggeration either I'm afraid :-(
But bad code is just ... bad code. People call this "tech debt" but it's not – it's just bad code. Probably took more and not less time to get that crap to work in the first place compared to if you had done it right.
I think one of the major mistakes the Right Way Guys make is to "solve" this by adding patterns and architectures and whatnot. But the solution is to just not have bad code like this.
I've seen all of the above play out more than once, with different companies with wildly different tech stacks.
To be fair to them, maybe they just care more about learning new stuff instead of shipping - so in their context all of the stuff they do makes sense. For me i know how to write good code so am no longer interested in doing it, except when it's necessary :) First you must learn how to write great code, then you learn when to write simple code instead.
Chances are, you'll get bogged down with these "maturity" things from the start and never build anything successful, or you'll go fast (perhaps catching a glimpse of success) until nobody can keep working on the project once those "maturity" things start to matter.
In the end, I think you're right though. As long as the code is reliable, then the shortest code is the best code (within reason, don't start playing code golf). It takes an awfully good abstraction to beat simply having less code.
Maybe it's a case of known the rules so you can break them.
> The Kesamutti Sutta states (Pali expression in parentheses):[5] Do not go upon what has been acquired by repeated hearing (anussava), nor upon tradition (paramparā), nor upon rumor (itikirā), nor upon what is in a scripture (piṭaka-sampadāna) nor upon surmise (takka-hetu), nor upon an axiom (naya-hetu), nor upon specious reasoning (ākāra-parivitakka), nor upon a bias towards a notion that has been pondered over (diṭṭhi-nijjhān-akkh-antiyā), nor upon another's seeming ability (bhabba-rūpatāya), nor upon the consideration, The monk is our teacher (samaṇo no garū) Kalamas, when you yourselves know: "These things are good; these things are not blamable; these things are praised by the wise; undertaken and observed, these things lead to benefit and happiness," enter on and abide in them.'
That advice is something that I found very useful in life even though I have become an atheist since I was in 8th-9th grade.
Which is a shame if true, because I sorely wanted to believe that the Buddha was this, um, enlightened.
[0] https://fakebuddhaquotes.com/do-not-believe-in-anything-simp...
"Do not believe in anything simply because you have heard it. Do not believe in anything simply because it is spoken and rumored by many. Do not believe in anything simply because it is found written in your religious books. Do not believe in anything merely on the authority of your teachers and elders. Do not believe in traditions because they have been handed down for many generations.
But after observation and analysis, when you find that anything agrees with reason and is conducive to the good and benefit of one and all, then accept it and live up to it."
Hope it helps. :)
Did I learn TDD when it was hip? Yes. Do I use TDD? No. But did TDD teach me how to write better code? Yes.
Same with languages I've learnt but not ended up using professionally. Everything teaches you something. You can't find a good middle ground without stepping a bit too far in both directions.
So while it's not TDD in the pure sense (it's more like Test Assisted Development) it is leveraging the spirit of TDD.
Sometimes. If the project/feature I'm working on lends itself to TDD, I use it. Generally speaking, all this guidelines and principles are good to know. They become a problem when people take them religiously. Ideologists are really a plague in our profession.
This is beautiful. So short, so apt, so instantly relatable and palpable.
> Eventually the honeymoon will end and you'll learn that programming is frustrating and messy regardless of which Right Way people use, and that you can also make great software without doing it the Right Way. Over time you'll learn fifty other Right Ways and learn to mix and match them to the problem at hand.
My impression though from last few years is that nowadays many developers get stuck being Right Way Guys and are unable to broaden their knowledge and views. This is sad and I do not know the cause of that if it is true. My speculation is that it has something to do with too short attention spans nowadays to efficiently expand knowledge in combination with being to comfortable in their current positions. Or maybe something with too much incentives to only learn specific frameworks and not basic knowledge of how things work “under the hood”.
That really impedes growth.
This includes state as in your code, state as in how many things you need to hold in short term memory to do your job, state as in how many project specific details you need to remember, all of it. State is the enemy. If you can derive it from first principles, always try to do so.
As someone who spent his entire childhood getting in trouble for forgetting things, it's been life-changing. Computers remember things so much better than my dumb brain.
Take walks!
Try different types of work. Learn about other job functions at your company. In big companies in particular, you may be doing things that just have to be corrected or worked around somewhere else, when you could make things easier for everyone.
I'd also expand on point 10 to add that talking to these people often gives you a better picture of what problems your software/dev work is trying to solve, and can help you identify pain points that you may not have noticed yourself. Remember that with a (very few) exceptions, software isn't written for the sake of it, it's written to solve problems.
Either way, nice list! Definitely has some useful advice there.
I think this point extends beyond the idea of guarding ourselves while reading the contents of good writers; it's also about how we should approach our jobs. Being a good writer will most likely improve your skills in dealing with other people. As software developers, writing and communicating with others is crucial to our work.
I would also recommend beginners to write about the challenges they have encountered, their experiments, and their thought processes, among other things. If possible, they should write essays. This will prove to be a really useful skill later in their careers.
We use code as a tool to solve problems. Code is the mechanism of achieving our goals, not the goal in and of itself. If we are coding just for code's sake, we'll deliver the wrong results. We need to be focused on solving problems, and if we aren't sure what problem our code is solving, we need to stop coding and figure that out.
"It is not your job to write slack messages". (Or emails, depending on the company.)
It can really feel like it is! Very much like the code one, it often feels like, well, this is the work; answering questions, collaborating, influencing the direction of the team and organization.
And communication is indeed important. But again, much like code, it's a tool that is used to create useful things, it's not itself the useful thing.
I am not sure whether this is a good advice - for a quite subtle reason: I do claim that most code (including most of the code that is written "for code's sake") does solve a problem, and most programmers at least unconsciously are aware of this fact - and that's why they write this "code for code's sake".
The issue rather is that other people (say, "the suits") want that the code solves a different problem than the one that the code solves.
The tricky bit is figuring what the real problem to be solved is, I agree. Ignoring that question and doing whatever comes to ones mind first doesn't really work so.
A central argument of me is that this situation "produce something to produce something" rarely happens - this is in my opinion rather evil propaganda from people who hate programmers and their way of thinking. Such code nearly always solves a problem - often one that the managers don't understand.
Just to be clear: it does happen that the code solves a problem in a bad way - this is where in my opinion the trope of "code for code's sake" comes from.
Some companies still use metrics like LoC to assess employee productivity. In such cases it might become a necessity to write code that's just there in order to look good on the next quarterly evaluation sheet.
More generally, "you are solving business problems by applying software systems"
That's how I describe this to junior folks. The goal is to make them focus on the business need, then they can sub critical thinking for MBAs/managers/PMs and do the right thing.
Saying, "It's not your job to write code," might seem technically false, but in terms of getting the message across, I think it's striking and it works well. And getting the message across is the goal of communication, moreso than being 100% accurate.
Just like solving the problem might be to remove code. Or to inform the user of tools that already exist but haven't been documented enough for the user to know about them.
A carpenter solves problems with wood. Sure, they communicate with customers, measure and draw, sometimes say "it can't be safely done"... But if you remove the part where they make a product out of wood, I don't think they are carpenter. They are.. a home solution specialist, something?
If my job was directing others to open source tools and removing dead code, I'm not a developer.
Having software to sell to VCs is valuable. So yes, sometimes you're payed to write code.
If you read really good code, and I mean really read it, like a book, and absorb it, then you will improve so much.
This kind of improvement is the most impactful, because you also spend most of your time as a programmer reading code than writing new code.
Also, if you become good at reading code, then you don't need documentation.
I think just reading down the text of a set of code files like a book has pretty limited utility. (Though better than not reading code at all!) It's like reading one of those choose-your-own-adventure books from start to end.
Starting from an entry point and then digging into methods from there is better, but being able to inspect the runtime state and get a sense for the data layout makes the experience so much richer.
That's kind of the problem and why it's a crutch. If you get better at reading code and reasoning about it without needing to use a debugger, it'll make you even more productive for when you actually do need to reach for it. The opposite is not true.
Being able to read code deeply in the setting of code review and point out structural issues without needing to execute that code or strap on a debugger is an enormous superpower, and one of the biggest skills that differentiates an early-career or mid-level engineer from a senior engineer in those that I've hired and managed. Over time, you do a lot more reading code than writing it if your codebase does its job successfully.
This perspective makes absolutely no sense.
This is like saying that the exercises in mathematical textbooks are a crutch because you'll never be able to read formulas if you interact with the ones in the book via the exercises given. This is the exact opposite of the case! The exercises are there to force you to "step through" the technical details in the text, to actively build intuition for the dynamics. If there were a way to spin up a math debugger to literally step through the details as you work through the exercises, that would be amazing. Educators would kill for that capability! And we already have it, essentially for free. But then out of some kind of misplaced sense of purity, tons of people have concluded that it's bad to use this incredible capability.
This is just bad pedagogy.
Edit to add: I feel like I didn't state this plainly enough: The way to learn things from textbooks is not to just read a bunch of different text, it is to interact with the concepts covered by texts. That's why textbooks all have exercises, and why educational institutions always ask students to do those exercises (and more). The advice to "read a lot of code" is like saying "read a lot of textbooks". But that's not good enough. You need to run the code, ask questions of it, test assumptions out; this is just like doing exercises in a textbook, and a debugger is a superpower for doing that active interrogation, while reading the text.
I never said to "read a lot of code" analogously to "read a lot of textbooks." I actually explicitly called out the practical context of code review, which is where you really learn and develop the muscle of code reading in a design critique setting.
You cannot get good at code review without getting very good at reading code and structurally reasoning about it. You get good at code review by doing it, and in particular doing it with other engineers who are very good at it and who can teach you how to do it. There are a lot of ways to do this that are essentially free (open source contribution is a great one); and of course, it's a mandatory part of what you'll need to do on the job as a professional engineer at any reputable shop.
Get good enough at giving and receiving quality code reviews and you'll find yourself reaching for your debugger less and less. That's because you'll be able to reason about code /in your head/. You can see how common and edge paths would evaluate without needing to execute it, because you've built the muscle to technically analyze and discuss it as it stands.
Go without building that muscle, and you'll lack the foundations that it builds for you, and you'll always rely on the crutch to make up for it. For what it's worth, this is what well designed software engineering interviews are designed to test for -- your ability to reason about and effectively work with code without being dependent on tools.
If you've never seen an experienced senior or principal engineer who uses zero tools solve problems 10x faster than you can because of their ability to do what I just mentioned, this is going to sound foreign. But if you ever develop the inclination to develop into such an engineer, you'll have to do what I just described.
Why can't you?
> Also, as one improves at reading code a develops a mental debugger that can be brought anywhere your eyes can.
This is definitely true, but that "mental debugger" is susceptible to incorrect assumptions about the runtime state at the point of execution. If this weren't the case, far fewer bugs would be written in the first place, as this mismatch about assumed vs. actual runtime state is where most bugs emerge.
Honestly not trying to be rude, but that would be because of how eyes work. The moment you do anything that goes beyond looking at code, is the moment you've met that limitation I described above.
The other part you brought is totally valid, it's just all about tradeoffs. If you prefer using a debugger in situations where I would read the code, then more power to you.
Actually, it's funny, because the original article talked about the One True Way (or whatever his exact wording was), and how we all go through a phase where we discover that for ourselves. I think this thread in a way has been an expression of that concept. Anyways, thanks for your thoughts, I'll remember this next time I'm struggling with the ol' brain debugger ;-)
Also, for every language there's a really important project written in that language, like SQLite if you want to learn C, or finagle if you want to learn Scala.
People writing essays are not writing it from some impossible point of knowledge or privilege. They're just you in the future.
You don’t need formal training, or “experts” writing blog posts, or the latest fad technology. Gusto and gusto alone can make you successful.
It's a direct and straightforward way of programming not ruined by object oriented thinking or any of the solid principles bullcrap.
What does the computer need to do? That is a powerful mindset to get into and building on.
However, I dare you to look at the kinds of code that "Jupyter notebook only needs to run once"-scientists write... Many of them have spent a lot of time hacking and can hack together something that runs and works on one input incredibly quickly. In a business, however, that's almost never what you want.
Maybe like a "bad hacked-together first instinct" is easier to correct and build on than "misusing or mangling an advanced dev paradigm that you're not even good to enough to judge whether is appropriate for this usecase."
This is so important and so general. Even writers who make a lot of their real world experience like Nassim Taleb are still read because they are good writers. No one reads Jeff Bezos' letters to his shareholders, because he's not a good writer.
I'm fortunate enough to have an office overlooking a small pond. When I'm frustrated I go to my window and stare at the pond for a while. When I'm really frustrated I walk down to the pond and stare at it for a while.
I also walk to lunch as often as I can (i.e. when it's not freezing or boiling outside). Highly recommend.
Ok, now I’m listening.
Also, #8 is the best long term advice for programmers. Walk.
That goes for all those talking heads on youtube too btw. They're not necessarily right, but they're good speakers/actors.
If it's unimportant to the project, agree and move on. E.g. "your code is badly written, but we've a tight deadline so I'm letting it pass the review".
If it was a real issue it wouldn't pass, this is usually just stylistic criticism (unless of course you've ignored good practices like SOLID etc ;) ) and indicative of a new senior who still can't differentiate between functional and problematic code issues.
Dependency Inversion I think is a poor idea though. It is fine if you must have many different versions. But I often thing one solid concrete implementation is better. where this really goes wrong is when people are so into Dependency Inversion that there is an IClass for every Class, doubling the amount of files, and <5% of these actually have more than one implementation.
IMO I think going by the original idea of Object Orientation from Alan Kay is the real winner: Its all about message passing.
While computer science / programming is very young and light on the science side, it has solid foundations in mathematics, and the mathematics that are true today will always be true.
So I argue (without providing any proof) that it is almost certainly a good idea to “follow the maths” in your learning journey. I think this is as true for numerical algorithms as it is for functional programming and type theory.
I'll make a different suggestion: set theory (which builds intuition around relational data modeling) and distributed systems (which builds intuition around building scalable services and software architecture) are by far the most important theoretical foundations I've had to actually apply at scale. That's followed by data structures & algorithms and discrete mathematics (for the rare times I really do need to write some optimized inner loops).
To a first approximation, type theory and set theory play similar roles. There has been a lot of noise in recent years around replacing set theory with type theory as the foundation of maths, at least in the context of proof assistants and programming language theory.
But nonetheless, I agree that knowledge of set theory can't hurt (and practically speaking, you can't go far in your maths journey without it).
(I would also note that functional programming is a special case of relational programming.)
Most of the volume of useful work to be done in programming is about state manipulation, which is mostly relational database operations, which is mostly about set theory.
I think every engineer should learn foundations that best equip them for the market long term, and prioritize their order of attack along those investments which will earn them outsized value. Data structures and algorithms, set theory and distributed systems equip an engineer extremely well for that.
I have a very hard time believing deep investments in functional programming and type theory would differentially pay off better.
Now, if one's goal is not to optimize for the market, then I think the answer is a lot more broad.
Any answer other than "yes" falls squarely in the anti-intellectual category... But of course all the usual pragmatism applies unless you are a point particle having indefinite lifespan.
That sounds like by "follow" you don't mean "study a lot"... What do you mean then?
For example, I prefer statically typed languages. It just works well with how my brain works. I am super productive. However I also understand that dynamic languages works better for some developers. That’s great! I will naturally seek out jobs and teams that prefer statically typed languages and they will seek out jobs and teams that prefer dynamic languages. No problem.
I believe other key parts of helping people advance are around teaching them how to read code and how to recognize/reduce unnecessary complexity, I don't really have solutions for that as of yet. There is plenty of text on DRY, SOLID, Law of Demeter, and so on, but I don't know how to move that knowledge from academic things one knows into tools for practical use.
This is how I think of Chesterton's Fence. A lot of people read it as saying "don't tear something out until you know why it's there", which is, I think, half of the point. But the other half of the message of Chesterton's Fence is that once you can explain to him why the fence is there, you're entitled to tear it out if you still think it's a good idea. The point isn't to avoid changing things, it's to always understand the reasoning behind the status quo before changing it.
Mine are simple -
Leave your ego at the door.. especially if you are a new/young talented or "prodigy" programmer.
Take any criticism on the chin. Be open minded and learn from it. Chances are they are not being negative towards you or your coding solution. In this indistry, people are going to be direct with their choice of words.
Be honest. If you dont understand, ask for clarification. If you are writing code or using some library you have not used before - let it be known. You are not saying "you cannot do it" - imply you are excited to challenge and learn. Most young devs are generally like this.
Co-workers will come in all shapes and sizes, and range from social to anto-social, alongside introverts or somewhere on the spectrum. I always try to meet-in-the-middle with everyone in this field.
Feel free to raise concerns or ideas but at the end of the day respect the decisions being made even if you do not agree with it. People above you like seniors, leads, etc, have experience and may have got through past projects and know things. Of course, if you are "correct" in many ways, I am sure you will be recgonised (eventually) as you gain experience yourself.
All this said and done --- Always be patient and dont worry if you are not "making an impact" in your department. Good things come with age.
Other than a means to gain advice, I've found this question a good gauge for collaboration compatibility.
I often ask it in interviews on both sides to give me insight into what someone currently values.
It's sort of like asking someone to define "better" be that in skill, or happiness or avoidance of pain.
My main interpretation of the post would be a high value placed on pragmatism, gained via a journey of experimentation. Put crudely there is no silver bullet but try a few for a while
I think point 10 is highly underrated in my opinion
Everyone expects juniors to make mistakes, you'll earn respect if people know they don't have to worry about you delaying or trying to hide issues.
Also, ask questions! Again everyone expects juniors to lack knowledge, and yet something about our schooling makes us embarrassed to ask.
Also, if you think you might fuck up big, partner with someone else first.
"If you're going to go down, bring people with you."
To follow advice #6: If you need the horror story to understand, look up "Thrombosis".
Software is complicated. Large, feature rich software is even more complicated. That's hard enough to manage as it is. The last thing you want to do is to throw a million of abstraction layers, frameworks, libraries, precompilers, transpilers, build steps, validation hooks, style checkers etc. into the mix. Each of them makes your project more complex by a certain factor. And not only do they add up - they multiply!
Now, that doesn't mean that you need to built everything bare bones without the help of any third party software - just make sensible choices. Unfortunately, developers are way too prone to add another shiny thing to the mix.
So here's how you decide if you really need something:
At first: You don't - continue as is.
Then: If the problem persists and the suggested solution keeps coming up, still refuse, but investigate the solution.
At last: If the problem persists, the solution seems well suited to address it and it keeps coming up - accept that you have the problem and adopt the solution.
I just had a junior dev rewrite some of my code so that: a builder calls a constructor which instantiates a builder factory which builds a builder then that second builder creates the object.
This whole system only builds one type of object. He thinks that his solution is better because it’s more extensible.
I can’t make him see why it’s bad.
> I can’t make him see why it’s bad.
Schools teach OOP as though adding new types of objects is the norm—like every type of software construct is actually a GUI widget in disguise and we're going to be adding new interoperable subclasses every other week, so we may as well get the infrastructure set up to make that easy.
In most real world applications, the only type of object that behaves that way is, well, GUI widgets. Nearly every other type of construct in a typical system will have at most one implementation at a time (possibly two during a gradual transition). Factories, builders, and the whole design pattern menagerie aren't particularly useful when for the bulk of a system's life they're all just proxies to a single constructor.
I don't know if there's a good way to teach this out of someone besides just letting them experience it, but that's the insight that he needs—different types of code have different maintenance characteristics, and the tools he's been given were developed for a very specific type of code and don't apply here.
Experience did the same for me.
It just takes some time.
I got a call from a guy saying "hey, this broke". I had not touched this system in 13 years. I had to re-remember a bunch of stuff. Some of the code was still a joy to work with. The parts that were hard were... obvious, and even then, I remember cutting corners, not documenting stuff, and overcomplicating things "just in case" (which mostly never happened).
There's little amount of someone 'telling' me ahead of time how much difficulty I was leaving for the next person (or even myself). It really seems like the only way to get this experience is with time. That doesn't mean you can't follow some best practices that turn out to be beneficial. But until you've experienced the downsides, you won't really be able to internalize the why regarding something being good or bad.
If you can easily read and understand some code, then it’s good code and you should leave it alone.
Debugging is twice as hard as
writing the code in the first place.
Therefore, if you write the code
as cleverly as possible,
you are, by definition,
not smart enough to debug it.
-- Brian KernighanRecursive descent, flex/bison, parser combinators… these are the tools to manage complexity. This is why lispers go so nuts once it fully dawns on them the power of manipulating the AST along with any other data structures in the program… it’s just a shame about all those parens!
We’re not writing machine code, most are not writing assembly or even C or Rust. Most hit the memory managed languages and it seems our abstraction has stalled, with endless language features applied to our current layer of abstraction. Its like goto programming before better abstractions were discovered.
This definition isn't absolute and neither is the definition by Brian. The truth is much more complicated.
Believing such implies it’s more difficult to ride in an aircraft craft around the world than legitimately beat Magnus Carlsen in a rapid chess game.
The reverse is frequently the case where running a marathon faster is more difficult than doing so slower.
And notepad++ had no easy way of showing trailing whitespace. So every commit was a dance of commit -> read rejection log -> remove trailing whitespace -> commit again.
You should worry more about how things are named, the number of abstractions used, and whether the code has any comments explaining the writer’s intent.
Just have an options file which is checked in with the code and enforce whatever is set in there works much better. You still avoids all the useless discussions about formatting while also allowing to set sensible settings which are consistent with surrounding technology.
Know plenty of people who call this job security
I don't think that business logic is dry per se. The problem in my opinion rather is that in other parts of the software project, there is much more openness with respect to
- trying out new things in new ways
- making the code more elegant
- seeking abstractions
- ...
than in the business logic area.
Believe me: for the kind of business logic that I see at work, I could immediately see ways in which the (non-trivial) business logic could be made much more elegant by using clever mathematical ideas, but suggesting such ideas to other colleagues or the bosses is like talking to a brick wall.
(I wish I made it up. This was what a CTO at a previous project did. 30-odd people were waiting and churning on while he was unavailable because he had to indulge his own things. And once they were beyond the point of no return, both he and the manager that greenlit this project quit, but stayed on as independent contractors. I believe they were demoted or taken off the project and eventually gotten rid of when a new manager was found)
Read the source code of popular software you use (including the libraries of your favorite language). You can learn esoteric knowledge about programming just by looking at other people's code. One benefit of OSS is that many eyeballs can shave code down to very efficient forms, and you can take those forms for your code.
I only seem to learn by moving back and forth between solving a real problem and finding just enough information to move forward one step. After some period of this, I'm usually able to read (and understand) a book or two on the subject, but never before. Maybe I'm a tactile learner? Not sure what to call it, but if you're not sure what kind of learner you are, try a variety of approaches and don't be discouraged if manuals don't work for you.
I probably "skim" the bash man page once every couple of years and I still find new things that I blipped over every other time.
As you said, it's a different than RTFM'ing, but it's an important clarification.
Thanks!
Also the purpose of reading a book isn't to become a master at implementing details, it is to get a good overview of the subject. You still have to practice implementations afterwards, but by having seen everything before your mind will now slot all problems much better and be more confident as you work through those implementations instead of looking up random advice on the internet.
My visual image is a tree. I first need a rough shape of the trunk and branches, before I can start adding smaller branches and leaves.
Bottom-up then feels like having a bag of random leaves, instead of a tree.
> You will look like a genius because you'll have an encyclopedic knowledge
> You can learn esoteric knowledge about programming
– and you will pay an incredibly steep price for it.
If you want to be effective, stay clear of this one. Systems are going to be increasingly complex to the point where it's absolutely impossible for any one person to understand it all and your best bet is getting efficient at poking them to figure out what's going on.
Knowing the system makes it very easy to poke the relevant people, find the relevant people and have meaningful discussions with those. Heck, it might even turn you into a meaningful person yourself.
The alternative is stumblong aimlessly around and parroting input from others without understanding the smallest thing about it. This is something LLMs excel at, for free. The former not so much.
Mastery is alluring - it's just not very effective and certainly really bad advice for new software devs, who are in the worst possible position to judge the margins and what is useful.
"lulz" -my brain
Systems are going to be increasingly complex
Coincidentally that’s where compensable expertise is.
Python language - Number of pages: ~206 ( https://docs.python.org/3/download.html )
Python standard library - Number of pages: ~2337 ( https://docs.python.org/3/download.html )
I don't know, but I have a suspicion you haven't read these cover to cover. Or maybe you have, for the latest version 10+ years ago. Is your advice to read the diffs when they update?
Also the ecmascript-262 spec version 5.1, also known as es5.
https://262.ecma-international.org/5.1/
They were actually pretty interesting reads, and not too long. Maybe I should see if there's a PDF of the Node.js and Go standard libraries.
I think there is plenty of time but maybe not in the types of work environments that are the norm nowadays.
It saves you time until the next version of the software gets released, or until the software is superceded by some other, shinier software.
But that leads to the other problem: knowledge is not intelligence. You’ve studied some Python module but never learned that you ought to use a different one instead.
- get someone on the team to give an introduction to get some basic knowledge of the system in question, where to find things and what portion of the system affects you
- read the documents relevant as per the previous point
- read cited documents
- start working, and look up stuff everytime you have to, dig as deep as possible
- unless you are 100% sure about something, look it up
- rinse and repeat, that grows your knowledge from immediately relevant stuff, to related stuff to general knowledge of the system
- ask question, always, be curious, listen, read and ask questions
It is a team sport, you don't have to know everything, master your stuff, and your interfaces with others (functions, sub-systems, teams and people, get a solid understabning of the overall system and relly on other like you for there parts.
Going alone, based on gut feeling and assumptions is not something I'd advice.
Also reading something cover by cover is not enough to retain the information. Not even close.
It doesn't matter how fast you read, you're not going to be able to read or retain all of that info.
I think there are times when this works and there are times when it will be a huge waste of time. In general, I think it's often very hard to tell which approach will be more efficient for you. As some sibling comments have mentioned, I think the way each person's individual brain works is a significant factor, but I think there are other potentially unknowable factors that are significant as well.
The best thing I've come up with to deal with this is to use an iterative-deepening-like approach. There's a reason this algorithm (pre AlphaGo) was the most common approach for many game playing programs. The general idea is to go a ways down a particular path but always keep in mind some notion of the global suitability of this path and when it starts to look too hard, back up and investigate some other approaches to at least a shallow (but a little bit deeper than before) depth. This lets you avoid potentially costly dead-ends for relatively low overhead.
(These thoughts inspired from this nice talk: https://www.youtube.com/watch?v=Z8KcCU-p8QA)
For me, the first time I mostly glance through and see the entire scope of things. I normally need to work with things at least a little bit first to really be ready for a more indepth read later.
This only works for people with excellent long term memory. I constantly need to look things up in docs and even my own readmes.
If you read at random it tends to send you down rabbit holes, unless you're grounded by applying your knowledge or you have the gist of the subject already. Rabbit holes are delightful if you're interested in them, not so much if you're going down them out of duty.
This is rather an argument against C#, .NET framework, and Java. :-)
A. Read an entire language's docs front to back. As you mentioned, maybe if it is some small, silly thing but for something like Python, Java, JS, etc... no fucking way. My brain would constantly glaze my eyes over. There is so much.
B. Retain the information I just attempted to read. Again, there is so much. It's insanely unrealistic for most people, I would think.
New developers see advice like this and immediately feel like they aren't cut out for this because people make this nonsense sound like something 'YOU MUST DO' to be a good developer. It's toxic, in my opinion. Maybe not intentionally so, but it really can kill a person's excitement.
This is especially important for any database you might be using. Language... meh, maybe...? But the DB - please do.
There's a balance to be found here that's likely different for everyone.
Also saves you from fragmented knowledge. When it is good enough, it will remain half-assed till your end.
At some point you will discover the Right Way to program, the thing which makes this all make sense, and you'll be convinced that the whole field would be so much better off if everybody else programmed the Right Way, too.
Item 14: Write an article debunking Right Way whether you actually believe it or not. Free notoriety == easy job offers2. The only purpose of software is automation. There is ultimately no other goal. When your peers start talking about frameworks, easiness, a bunch of tools, or other bullshit realize they have absolutely no idea what they are doing. Typically that occurs from some combination of narcissism, self-preservation, and stupidity. Either way when too many bad decisions occur your peers will burn you.
3. Becoming excellent at software is no different than becoming excellent at absolutely anything else. Software isn’t special. Practice. The people that argue against this are lazy and stupid. As an example of talent look at the Polgar sisters.
4. Just like with absolutely everything else being excellent at software means having enough challenging experience to form a vision around risk management, cost analysis, and unnecessary repetition. All of that should be tempered against novelty and asking the right extraordinarily critical/harsh questions. Most people don’t do any of this because of some combination of real life constraints and cowardice.
I feel like people exagerrate this idea to prove a point that, ultimately, sales is the gateway to money. Which is fair and important to keep in mind. But, worded like this, it goes too far. Sales and marketing do cost money. They can cost a lot of money, and it's not always as tangible as real product features. Non-marketing people tend to handwave away how hard it can be.
And the product is important. It's much easier to sell a product if it has the features a client is looking for. To do otherwise is a whole different game that will also cost a lot of money but is feasible given certain conditions. For example, building a really strong brand where trustworthiness is more important than price/quality.
To your point, the goal of "trustworthiness" is to translate into more future sales.
1. A high quality product reduces the effort on the sales people. It’s nice when a product sales itself on quality alone and it’s also nice when sales can just bank on word of mouth marketing.
2. High quality products cost more to build but less to maintain, scale, extend. That results in predictability that is otherwise absent and expensive.
I assume this ignores hobbyist coders.
This relates back to a course I took about software architecture. There's a guy called Johannes Siedersleben who separates software into three blood groups: A, T and 0.
According to his model, type A contains domain-specific business logic, type T technical code and type 0 is the glue. One should strive to keep these highly cohesive and especially loosely coupled.
I found this an interesting way to think about software and it made me realize that a majority of projects contain mostly type A code while most stuff university teaches is how to write type T code.
Or, can you explain further? I'm not clear, for example, what you mean by "technical code."
And when you mention "the glue" are you talking mainly about APIs and protocols of all sorts (defined loosely)? This is where the edges of systems coincide and intended side effects reside.
If you are interested I can look for some older material, just shoot me an e-mail.
Yes, I understood that type 0 does exactly what you describe - Covering the edges of type T and type A systems.
Otherwise, yeah, the separation of domain specific code and "infrastructure" code is not novel at all.
Everywhere else, your worth is the value you generated multiplied by the number of people it interacts with.
The closer or more direct the path is from the work you do to the value generated, the more you will be valued in that company. This is why Sales can be valued so highly, but if you implement X to win contract Y worth Z where Z is a very big number, your worth is quite clear and it's obvious you should move on if you're treated as a cost in such cases.
I do not like this comparison, mostly because it leads to out weight one for another. We currently have the situation that we are understaffed in dev and overstaffed in sales, but sales does not generate enough revenue to justify their existence. However, we can also not deliver as much features as we like, because the dev department is too small.
The tools only start mattering when the maintenance and usage of the tools becomes a heavy constraint to doing what you actually want to do (big tech). That doesn’t actually happen very easily.
1. It's tautological that you can't make money without some form of sales. And it's tautological that if you're employee you cost money. Sure you can sell anything even a rock (see "Pet Rock"), but if the company is making money by selling software, then yes, the software makes money, otherwise your company would have its sales trying to sell rocks.
2. Games aren't for automation. They're for players to have fun. People have also written software as some form of art. You are not in a position to dismiss them as devoid of purpose.
3. There's more to "practice" to become good at software. There are specific tricks, approaches and attitudes to become good at it.
4. "risk management, cost analysis"... What are you talking about? There are people who write great software who don't deal with this crap (because they can offload this to somebody else). Heck even great companies sometimes do this (by offloading risk to investors). You're delusional if you think "risk management, cost analysis" is needed to be excellent "with absolutely everything else". Was Michael Jordan a master at cost analysis? Was Einstein an expert in risk management?
I'm surprised you have the audacity to write with such an absolute and authoritative tone. If anything, being good at software is to recognize edge cases and situations outside of the stereotypical scenario. It seems you've done the opposite and generalized your personal experiences into some kind of absolute truth.
1. You are either actively generating money directly with your activity or you are contributing to something else that does but you are only doing a single thing at any given moment. Everything else is just pandering to justify your existence.
2. Games can be anything. You don't need a computer to play Sudoku. What separates video games from paper games is automation. Nobody has so far proven this wrong.
3. There are no tricks to practice. You are over coming challenges or spinning your wheels pretending to do so. That is why beginner experts are so common.
4. I guess you have never managed people or products.
> I'm surprised you have the audacity to write with such an absolute and authoritative tone.
I don't know you, but your words indicate I have been doing this work longer than you have been alive.
That's because it's not even wrong
Instead of excellence, strive for "working code", collaboration, quality, velocity, improvement, shipping the right thing at the right time. Use debt wisely and move forward.
Software creates value that you can exchange or rent in exchange for money. All the big software companies know this, their software developers know this, and that's why those developers are well compensated.
Tools unlock valuable opportunities and this becomes more true with superior technology. The opportunity for accessing value is not profit though. Profit only occurs when income exceeds expenses. The means to access income still costs money, such as Customer Acquisition Cost, whether those means are things like better tools or advertising. Superior software may reduce the time per customer transaction, cost per customer transaction, or increase the number of simultaneous transactions but its still those transactions that drive profit. The software is just a contributing artifact. Most of those transactions probably cannot occur without the help of some software, but without the business transactions the software is just an expense not making money.
This kind of digital signal amplification is distorting any and all knowledge about our world! These will be known as the Digital Dark Ages to our great grandchildren. What, you say, with access to all this information how could it be? Are we not information technologists? Isn’t the answer obvious? Signal to noise. What’s the point of the information if the message is too distorted by the transfer medium to be coherent?
The trick is then being skeptical without becoming cynical, not to withdraw but to balance. Probably to slow down. Like described by the last word in the quote, to be conservative. Chesterton’s Fence was shattered by an electric truck going 0-60 in 3 seconds, and as wood and stone splintered off of stainless steel and bulletproof glass, we all celebrated the global democratization of politics, labor and information. How do the Arab Spring, Lyft, and Google look 12 years after the party peaked?
You absolutely should learn languages (as but one example) outside the TIOBE top 20. You should be very selective in where you choose to implement them. (with exceptions, of course - TypeScript is likely a pretty safe choice now, but maybe wait to hitch your trailer to Mojo in a production environment.)
Again, all of this is situated in a world of upvotes, advertising, global politics, venture capital, smartphones in every pocket, etc. The systemic effects are similar across a broad range of knowledge dissemination.
It’s time to hit the brakes.