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.
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.
Okay I guess I'll take the bait and assume you are legitimately confused and that your original comment was in good faith.
When you say something like
> You sound like you saw the phrase "Right Way Guy", felt it sounded pejorative (it's more gently poking fun at a common thing), and decided it must mean That Type Of Guy I Don't Like.
you might think that no one should get offended by this because you are being objective about your thoughts. But it doesn't matter that you're "just" sharing your thoughts. These thoughts are hurtful to the parent as evidenced by their reactions. They're hurtful because people don't like being wrong nor do they like being told that they're upset. If this isn't clear to you, then you have my deepest condolences because I expect you often unintentionally offend others.
If I may offer unsolicited advice, you can avoid this kinds of unpleasant reactions by mincing your words. I know a few people who speak like you did and they all are so confused when I tell them this because they think readers would be offended that they are padding their message with unnecessary formality and fluff. But without it, their message is often curt.
I see this interaction play out all the time on HN (including my response), so I hope my response is not in vain...
I'm offended that they emitted actual word salad at me followed by a random (and actually wildly offensive! or it would be if it made any sense) accusation that was unrelated to anything even close to anything I said.
That's what I mean by "bad faith".
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.
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.
Maybe it's a case of known the rules so you can break them.
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.
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.
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.
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.
> 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.
"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. :)
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...
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.
Hmm... Wait. Is that worse?
This is beautiful. So short, so apt, so instantly relatable and palpable.
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.
> 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.
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.
"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.
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.
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 ;-)
I like your call-out of the "one true way" section. What I was thinking in that section is that my experience, having now traversed a number of "one true ways", is that: 1. Very nearly all tools and techniques are truly useful in some way in some circumstance, and 2. Not all "one true ways" are created equal; some tools and techniques are more useful than others and better stand the test of time.
In my view, using a debugger to understand the runtime state while reading and exercising code (especially when it is unfamiliar) is one of those techniques that is broadly useful and never out of date. But that's not a totalizing view, it isn't the "one true way", obviously nobody only reads code while running it within a debugger, nor should they! But dismissing its utility for this use case of understanding code more deeply is, in my view, just odd.
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.
But this thread is not about people using this muscle, it's about people developing it afresh and further exercising it. What you described with senior engineers doing code reviews and such is analogous to a ballet dancer on stage performing, but I'm talking about doing a thousand pliés in a practice studio. The stage doesn't have a barre or a mirror, but the studio does, and it would be foolish not to use those useful tools when exercising.
I'm not totally sure if we're just talking about two different things - use vs. exercise - but a plain reading of your comments makes me think that you think the best way to improve one's structural reasoning (or "mental debugger" as another commenter put it nicely) skills is to just read more code. But I'm sorry, that's just not right. It is much better for building a good mental model of how code executes to simultaneously inspect and interrogate it as you're reading. It isn't necessary, it's just better.
A crutch is just not the right analogy. Rather, it's an aid that makes exercise more effective so that you're stronger when it comes time for game day.
Or, to come at this from another angle: Surely you agree that just reading code is not actually helpful for developing the reasoning ability you're talking about in your comment. Wouldn't you agree that novices need to run the code they read, to see what it does? Otherwise they are guessing , and as novices, they are almost certainly guessing wrong. Without anything to check their guesses against, they are likely to just assume they're right and internalize that likely-wrong mental model. I certainly had to painstakingly undo a lot of my incorrect mental model from bad guesses early on. The more that can be avoided, the better!
If you agree with that, which I suspect you do, then I'd put it to you that a debugger is just an efficient and effective tool to better aid in this process of guessing what code does and then checking those guesses, in order to further develop and internalize a correct mental model of how it works. It's like if you could run a unit test surgically exercising exactly the code path you're interested in, exactly up to your breakpoint, and assert on exactly the program state you're guessing about to confirm or deny your hypothesis. But you can do it interactively, without needing to write test code. It's an amazing capability and learning aid! It's very bad advice to tell people not to use it as they are learning.
I've already said twice, both in the original comment and in the follow up, that my point is about applied code reading in the context of code review, not in a vacuum. The first time you decided to respond to a made up point which I never made, I clarified it. Now that you're doing it a second time, it's clear you're arguing in bad faith and putting words in my mouth.
I wonder why you keep on arguing against a strawman point that I never made rather than actually responding to my argument. Is it because you are incapable of understanding the point I'm making? Perhaps. Is it because you're deliberately ignoring it out of cognitive dissonance as you know it would weaken your argument, and you'd have to admit that you're arguing for something which is the wrong strategy? I hope not, but that's my best guess.
The rest of your comment is impractical. If a novice is struggling with understanding and working with a piece of code, do you really think the best way for novices to learn is to "figure it out" with a debugger, or do you think they should ask for help through code review or pair programming with someone else working with them on the project?
You seem to be arguing under the assumption that software engineering is a solo sport. I am arguing that software engineering is a team sport and those who treat it like a solo sport tend to underperform and plateau in their skill development.
I stand by what I said. Debuggers are a crutch. Crutches can be useful but you shouldn't rely on them. Learn how to reason about code in the abstract (which you learn to do by learning fundamentals of computer science and applying them in a team context with others who can) and you won't need it because you can compile the AST of the codebase in your head. Moreover, this skill is MOST critical to develop when you're early in your career because it's when you have the neuroelasticity to learn new ways of reasoning about and problem solving with code. I was forced to do this by early career engineering leader mentors and while painful and humbling, I am very thankful for it because it put in place the practical fundamentals for me to architect large, performant, scalable and revenue generating systems from scratch with very little issues.
If someone thinks that's impossible to learn whether late in their career or early in their career, that speaks more to their shortcomings than to an issue in the technique. For what it's worth, many of the strong early career engineers I've worked with (1-2 years experience max) have also been able to do this, and often times even better than many mid to late career engineers. As you may expect, these strong early career engineers end up running circles around their more experienced counterparts pretty quickly.
Ok, but that's not what this thread was about before you replied. The OP literally starts with the words "advice for new software devs". So I assumed that, rather than just being off-topic, you must be using that as an analogy for what we were actually talking about.
The reason I keep coming back to the topic of the thread is that it is the topic of the thread. It honestly just took me awhile to figure out that you actually did just want to grind an axe on a totally different point.
> If a novice is struggling with understanding and working with a piece of code, do you really think the best way for novices to learn is to "figure it out" with a debugger
Um, yes, definitely. Or at least, it is one extremely valuable tool they should learn how to use effectively. Another very valuable genre of tool that has emerged very recently is things like chatgpt. And then there's good old fashioned reading of code, books, documentation, articles, etc.; those are useful, but the interactivity of a debugger or chat assistant is better.
> or do you think they should ask for help through code review or pair programming with someone else working with them on the project
For one thing, "novice" does not only mean "entry level employee", it also means students. But both students and people early in their career should be taking advantage of both high-touch 1:1 support like code reviews and pair programming, when possible, and also muddling through things on their own, guessing wrong and figuring out what the right answer is and why their guess was wrong. It is not possible when learning and deepening a new skill to have an expert available for individualized attention at all times. Individualized attention from an expert human probably is indeed the best way to learn and develop skills, but it doesn't scale.
> If someone thinks that's impossible to learn ...
Who said that? It is obviously possible to learn things while ideologically rejecting readily available tools that can help you learn more efficiently and effectively, it's just extremely foolish.
For instance, a tool that seems to have been readily available to you, which you seem to have used effectively, was the support of an experienced mentor. It would have been very foolish of you to reject that. But by your logic, using an experienced mentor to help you develop a new skill is a crutch that you must reject because you won't be able to run all your code reviews by a mentor later in your career. But of course you can see why that's stupid. But it's the same thing you're saying about debuggers. "Don't use a tool to learn because then you won't be able to function without it later". It's just not how learning works.
Any tool that helps a novice build a more accurate mental model of a subject is a benefit, not a crutch. Holding an ideology in opposition to such tools is foolishness.
It looks like you really don't have a substantial argument or credible results to show for why your proposed approach is better, so I'll refute this one: no, any tool that helps a novice build a more accurate model is not necessarily a benefit. It's the same reason that you don't ride a bicycle with training wheels forever, and the same reason singers who can't sing without auto-tune atrophy in their development.
I'm glad you're at least conceding the value of individualized attention from an expert human being the best way to learn and develop skills, but I disagree with you that it doesn't scale. In fact, I'll refute it most strongly -- it's the only thing that /does/ scale.
If you are a novice engineer and you want to progress as fast as possible, start doing real code review as soon as you can. As I mentioned earlier, you don't need to get that from being gainfully employed -- you can and will pick up all of these skills in open source contributions. Start contributing and you'll get feedback. Work on the feedback and you'll start learning what code review is all about in practice. Learn what code review is all about in practice and you'll stop fumbling around in the dark with a debugger.
You only have so many hours in the day. Spend it on what really matters, and spend it on the most important muscles. Do your deadlifts and squats rather than ab crunches.
You think people should be taking advantage of human support to learn by actively doing, and I think they should be taking advantage of both human support, if available, and also whatever computer tools are at their disposal independently.
The only reason I started arguing with you is that this prideful machismo ideology of disdain for useful tools that is common among programmers has become a giant pet peeve of mine, over the years since I held that foolish ideology myself. I'm not arguing with you, I'm arguing with myself a decade ago, when I could have avoided a lot of silliness.
> You only have so many hours in the day. Spend it on what really matters, and spend it on the most important muscles.
I also only have so many hours in the day, frankly not nearly enough as it is to do my work and take care of my family, and I don't want to spend any of them trying to figure out how to mentor people who send broken code for review without bothering to first figure out why it doesn't work how they expected and how to fix it. That is not a valuable use of anyone's time; there are plenty of tools available to off-load this to computers, without taking advantage of someone else's "only so many hours in the day".
What I am interested in mentoring people on in a code review or pairing session are the interesting non-mechanical facets of the craft. I love discussing that stuff. But please don't come to me with "I don't understand why this data structure holds this value at this point in the program"; you can figure that out yourself and learn something on your own in the process.
Candidly, I don't know how constructive this conversation is at this point; given that you've mentioned "I also only have so many hours in the day, frankly not nearly enough as it is to do my work and take care of my family, and I don't want to spend any of them trying to figure out how to mentor people who send broken code for review without bothering to first figure out why it doesn't work how they expected and how to fix it" I find it hard to believe that being one of the best builders in the world is really your goal or that coding is anything more than a vocation for you rather than a calling. And there's nothing wrong with that, but it's going to mean we will simply talk past each other having two completely different conversations.
However, my advice is for those who are not content to be good enough at writing software to maintain a stable job in tech until retirement, but for those who want to go above and beyond that, and stop at nothing to be the best of the best and reap the rewards, internal fulfillment, and sense of purpose that comes with that. Realistically that isn't and it shouldn't be most the goal of most early stage engineers in the field -- it's an expensive goal that even if attained only will make a very specific kind of person (like myself) fulfilled. Your advice is likely good for the former category, while mine would be poor.
For those in the latter category, I'll contextualize my advice based on the this very well written blog post by Dan Luu about the difference between p95 proficiency and p99 mastery. You can sum up my argument as stating that overreliance on debuggers (and other tools such as IDEs) is absolutely something that you see in p95s that you don't see in p99s. P99s can utilize debuggers, IDEs and other tools but it doesn't materially affect how quickly they can execute because of how well trained, fast and accurate their "mental math" flavored problem solving ability already is [1]. If you're curious, please take a look through the linked blog post and see how much you agree with it.
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.
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."
You don’t need formal training, or “experts” writing blog posts, or the latest fad technology. Gusto and gusto alone can make you successful.
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.
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?
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.
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.
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.
* All our code must be linted / formatted
* All their code must be ignored.
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)
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 KernighanThis 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.
Reread my post. I literally said neither definition is absolutely true.
Further the quote wasn’t suggesting equivalency. Rather intelligence as one bound on debugging, which is clearly true as can’t get a flatworm to do it. When trying to debug really clever code the easiest solution can be giving up and starting from scratch.
Clearly you don't think bugs are all solved in seconds and limited only based off of intelligence. A harder bug often needs more time to solve. This is common sense.
You're just sinking with the ship now.
This isn’t a discussion about all bugs but the class of bugs created from dealing with clever code. Very difficult bugs may be fairly quick to solve in comparison to simple bugs that require some long process to replicate. Time to solve really doesn’t map well to difficulty.
>Clearly you don't think bugs are all solved in seconds and limited only based off of intelligence.
False, you clearly missed me stating it intelligence was “one” limitation not the only limitation. Poor tooling can be a massive pain among many other things. Again though this is talking about debugging a very specific kind of unnecessarily complex code.
It does. A bug solved in seconds is usually considered less difficult than one solved in weeks. It maps easily.
>False, you clearly missed me stating it intelligence was “one” limitation not the only limitation. Poor tooling can be a massive pain among many other things. Again though this is talking about debugging a very specific kind of unnecessarily complex code.
The quote was suggesting absolutism one limitation. By showing the existence of an equivalency I've shown the quote is not absolute. Therefore the quote is not intelligent. Therefore your statement is false and nonsensical.
Luck wildly impacts how long ‘difficult’ problems take to solve. I’ve solved bugs in seconds someone literally spent weeks and asked multiple people to help them solve and I’ve had the same thing happen to me.
Thus actual solve time and absolute difficulty are almost orthogonal.
> The quote was suggesting absolutism one limitation. By showing the existence of an equivalency I've shown the quote is not absolute. Therefore the quote is not intelligent. Therefore your statement is false and nonsensical.
Again no, it was saying one limitation becomes significant in a specific situation. Often these bugs may not actually take long to fix, but you’ll suffer when dealing with them. Even strait forward off by one errors can be annoying when you have to reason about really tricky bits of code.
That feeling where you spend an hour staring at an IDE with absolutely no clue what’s going on sucks even if it doesn’t take that long to actually fix the issue.
No it just means luck is another factor. You have luck, intelligence and length of time. Time is correlated with possibility right? You can get lucky and guess the probability on the get go.
Either way you introduced a third possibility here which goes further to illustrate that this quotation is inaccurate and not intelligent.
>Again no, it was saying one limitation becomes significant in a specific situation. Often these bugs may not actually take long to fix, but you’ll suffer when dealing with them. Even strait forward off by one errors can be annoying when you have to reason about really tricky bits of code.
False. You are absolutely wrong. The statement was made without qualification to a specific situation. Therefore it is made in the context of the universal situation meaning absolutist. Sinking with the ship again.
>That feeling where you spend an hour staring at an IDE with absolutely no clue what’s going on sucks even if it doesn’t take that long to actually fix the issue.
So? This doesn't have anything to do with the topic at hand. The topic at hand is the quotation is wrong. How you feel during debugging is off topic.
The overall stamens includes an “if you” which is a qualifier. So you seemingly don’t understand what those words mean and objectively wrong here.
He is saying if you write code as cleverly as possible then in ALL situations it will be impossible to debug by you, which is false. The quote is not intelligent.
You know all of this you're just sinking with the ship and trying to manipulate the situation your way while throwing insults at me on my ability to understand language. Insults are a signature move by someone who has clearly lost the discussion and you've lost definitively.
I think we're both done here. After that insult there is no further need to continue the conversation. Please leave.
And no it’s not saying in ALL situations you can’t solve ANY bugs. You only finish debugging when you solve every bug not just 1 of them. Further sometimes you’re going to write a clever bit of code that doesn’t contain a bug and thus doesn’t need to be debugged.
So it’s saying writing buggy code is easier than correct code, so avoid writing clever code or some of it is going to stay buggy. That’s what the quote actually means.
PS: Also, that wasn’t an insult it’s a statement of fact. You’re trying to twist the statement as not being qualified but it’s got a qualifier.
You're a liar. I clearly am typing english and reading your responses. You're typing to me in english so you know I understand it. What you said was therefore with 100% intent malice because it's simply not true. You are not a moral person. You're just an asshole and you know it. THIS statement can be claimed to be a fact, not yours, not even in the slightest.
I mean you know what happens when you call a stupid person "stupid" to his face and then say it's a fact? It's not an insult? Just a fact? You know this. No need to spell it out. You're an ass hole.
>Nope, nobody writes every single line of code in a program as cleverly as possible attempting to do so generally means you don’t finish.
You're just making stuff up at this point. A quotation made around a situation that can never occur according to you? You're just lying now.
>And no it’s not saying in ALL situations you can’t solve ANY bugs. You only finish debugging when you solve every bug not just 1 of them. Further sometimes you’re going to write a clever bit of code that doesn’t contain a bug and thus doesn’t need to be debugged.
No you're just adjusting the meaning to fit your agenda. You're going at a bit of of a stretch here. This conversation has descended into way to deep of pedantism thanks to your attempt to twist things in your favor.
>So it’s saying writing buggy code is easier than correct code, so avoid writing clever code or some of it is going to stay buggy. That’s what the quote actually means.
No. It's simplistic to say that clever code tends to be buggier. This guy took the extra step to say that clever code is "by definition" not debuggable. Again twisting the situation to fit your agenda.
Man you're done. You need to stop with the insults and stop with these pathetic attempts at explaining your point of view.
Ignorance doesn’t mean stupidity it means you don’t understand something. It’s possible to gain understanding when you accept you’re wrong and try and learn, but lashing out means you will forever wallow in ignorance.
> generally means
“can never occur” this this is why you don’t understand. You need to actually read what was written not whatever nonsense comes into your head.
You only need to debug code that’s not correct. Therefore logically when talking about the effort to write code vs debug that code they don’t mean the effort to write correct code vs debut correct code. Instead it’s the effort to create incorrect code vs debut that incorrect code. Any other interpretation is nonsense.
Recursive 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.
Know plenty of people who call this job security
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 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.
Experience did the same for me.
It just takes some time.
> 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.
Software development is reliant on self-learning, but still, some education can be outright damaging.
[0] https://www.dataorienteddesign.com/dodbook/
[1] For instance, objects in OOP are typically bundled with other data related to the object. As an example, in OOP a Door object could have float X,Y,Z coordinates, an enum for type of door it is, a bool for opened or close etc. This leads to inefficiencies in cpu cache usage when you are iterating through a list of doors and not using every field of the door object.
See this GDC talk for why this matters in the gaming world: https://www.gdcvault.com/play/1022248/SIMD-at-Insomniac-Game...
If you can easily read and understand some code, then it’s good code and you should leave it alone.
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.
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.
> 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.
"lulz" -my brain
That is, honestly, something I expect from people in a professional environment.
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.
Edit: Regarding Linux, you are propably not touching every function or component of Linux neither. The less you are concerned, the less important it is for you. And less you uave to read it. That being said, a fulltime Linux OS dev propably should have a solid understanding of the complete OS to begin with.
You are obviously picking and choosing your documentation based on how easy it is to read. So your advice isnt universal. Clearly you don't fully follow it.
There's a lot of contrarian opinions here due entirely to the fact that people won't read certain documents for the same reason you avoid reading the c++ spec.
How deep and broad your understanding has to be depends on:
- your team, nobody can know everything alone, it is a team sport
- your specific use case, I cannot help you with that
- complexity of your use case
- your role, if you are responsible for graphics under Linux, sure as hell you read that part of the Linux documentation, front to end, multiple times and master it
- and, as always, know your system, stack, tools and documentation well enough to realize when you have to look stuff up and where
I don't need your help. You need it. I'm helping you realize your statement is wrong.
First you make a statement saying one should read all the docs. Now you say devs should read the relevant docs. Devs do the later anyway. Your argument just evolved into the point you're arguing against.
Clearly you didn't mean to do that. You just meant to read more docs then you normally would on topics a little further from the relevancy at hand. But people are responding to you based not off what you meant but what you said.
Not every statement has to be taken literally, it seems so that on HN, more often than not, one has to be incredibly specific in ones comments. That is like talking to genie or something, really frustrating. I kind of assumed, and without going through all my comments I think I also mentioned it, that by "all the docs" the meaning was all the relevant docs, I even specified that explicitly later on, didn't I?
So, ehy exactly do you think that reading jib and task relevant documentation is not necessary, or even the comoletely wrong approach? Seriously curious, because I run into such people ever so often at work and usually fail to explain to them why they actually have to read that stuff if they want to be a usefull member of the team. Understanding why they have that opinion would really be helpful.
No but even if C++ is the central language of my stack your comment can reasonably be interpreted as suggesting me to read the entire C++ spec. That's not an outlandish interpretation given how many people interpreted what you said this way.
>So, ehy exactly do you think that reading jib and task relevant documentation is not necessary, or even the comoletely wrong approach?
Did I say this? No.
I do the same with everyone, actually, myself included. Plumbers have to know the specs of their tools, materials and the regulations as well as principles of installation. And they do, the good ones at least.
And the easiest way to get that familiarity is reading the damn documenents. If you cannot be bothered with that, well, let me say I am happy I don't have to work with you.
I just did what. Be clear with Your sentences.
>If your job is C++ development, yes, I absolutely expect you to be familiar with the full C++ documentation and master the parts relevant for your specific usage of it.
So you were unclear. You want someone to master only parts of of the stack but read the full spec. This is completely inconsistent with what you said earlier. You are moving the goal posts. Still it doesn't Make sense to read 1800 pages of the C++20 spec.
Do you read the English dictionary because you use English?
>And the easiest way to get that familiarity is reading the damn documenents. If you cannot be bothered with that, well, let me say I am happy I don't have to work with you.
Then you would be happy to not have to work with the overwhelming majority of programmers on the face of the earth. You being in the minority would make you the problem. Not others. Programmers in general read the spec and docs relevant to the task at hand. They do not generally read the full formal specifications and documentation of what they need.
Systems are going to be increasingly complex
Coincidentally that’s where compensable expertise is.
This only works for people with excellent long term memory. I constantly need to look things up in docs and even my own readmes.
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.
This is rather an argument against C#, .NET framework, and Java. :-)
Also saves you from fragmented knowledge. When it is good enough, it will remain half-assed till your end.
- 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.
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.
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.
Some of us need a certain amount of clarity and structure before we can feel good. This a great! Especially if we're aware of what we need and figure out how to get it.
Others of us have trouble building from the roots, and we're more effective probing around in dimly lit fog with occasional bits of moonlight illuminating leaves.
Eventually, we may both find ourselves in a well-lit forest, but we approach from different starting points.
The important thing (for me, at least), is to know which path I need at a given point in time and for a given context.
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.
It saves you time until the next version of the software gets released, or until the software is superceded by some other, shinier software.
I think there is plenty of time but maybe not in the types of work environments that are the norm nowadays.
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.
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.
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.
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.
There's a balance to be found here that's likely different for everyone.
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.
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.
A better way to put it, is a developer about thinks he's excellent. What someone thinks is, the majority of the time, not inline with what he actually is. Especially for developers who think they are excellent. Looking at you Brian Camacho.
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.
Yeah.
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.
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
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.
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.