[HN Gopher] Reflections on 10k Hours of Programming
       ___________________________________________________________________
        
       Reflections on 10k Hours of Programming
        
       Author : herbertl
       Score  : 300 points
       Date   : 2021-08-06 13:27 UTC (9 hours ago)
        
 (HTM) web link (matt-rickard.com)
 (TXT) w3m dump (matt-rickard.com)
        
       | devwastaken wrote:
       | I appreciate these, but in my experience it's not that relevant.
       | The harder problems in programming are more of knowing your
       | ecosystem. Knowing the design patterns necessary to create well
       | meaning, understandable code in the first place. This is
       | especially cumbersome when working on projects with complex data
       | patterns.
       | 
       | For example, working with GUI applications and C/+ can make your
       | code a big pile of garbage really quickly because representing
       | your data in something like an ORM is not standard, you can't do
       | the many tricks like getters/setters in C/+, but you can in
       | Python, or C#, etc. The benefits of VM languages are, in my
       | opinion, not appreciated enough.
       | 
       | In my opinion knowing the right tools for the job is far more
       | important than how you comment your code, how you name your
       | variables, or anything else. I wish there were more posts where
       | people impliment an application with multiple tool sets and
       | compare them, give insight into what some things are good for and
       | not. "Tool Benchmarking" might be a good term for it.
        
         | rckrd wrote:
         | Lucky for you #6 is "Have a wide variety of tools and know
         | which ones to use for the job." :)
        
         | nerdponx wrote:
         | > I wish there were more posts where people impliment an
         | application with multiple tool sets and compare them, give
         | insight into what some things are good for and not. "Tool
         | Benchmarking" might be a good term for it.
         | 
         | I recently started working on a project like this. It's hard
         | work.
         | 
         | Building a complete tool in _one_ language takes a long time.
         | Not to mention 2, or 5.
         | 
         | Moreover, many (most?) programmers are only "fluent" in one or
         | two languages. Even if you "know" a language, you might not
         | know the full build toolchain, or you might not know common
         | idioms, etc.
         | 
         | Most people probably want to work on building
         | new/interesting/fun stuff, not reimplementing the same toy
         | program in several different languages.
        
           | rckrd wrote:
           | I've actually found that knowledge diffusion between
           | different languages and different types of developers can be
           | significant - e.g., game developers work much differently
           | than distributed systems engineers.
           | 
           | Not always, but sometimes, an interesting knowledge arbitrage
           | opportunity when fields start to collide.
        
       | greyman wrote:
       | > 4. Syntactic sugar is usually bad.
       | 
       | I agree now, after switching from Python to Go.
        
       | ipnon wrote:
       | "And the disciples came, and said unto him, Why speakest thou
       | unto them in parables? He answered and said unto them, Because it
       | is given unto you to know the mysteries of the kingdom of heaven,
       | but to them it is not given. For whosoever hath, to him shall be
       | given, and he shall have more abundance: but whosoever hath not,
       | from him shall be taken away even that he hath. Therefore speak I
       | to them in parables: because they seeing see not; and hearing
       | they hear not, neither do they understand."
        
       | boyadjian wrote:
       | Don't be afraid of simplicity: The most simple it is, the better
       | it is
        
         | rckrd wrote:
         | Agreed!
        
       | barce wrote:
       | There's lack of proof to back up the 10k hours. I get that he has
       | worked 15 years at prestigious companies but I have to take his
       | word on it. Some aphorisms jelled with me but other's didn't, so
       | we're again at a "he said; she said" impasse.
        
         | rejectedandsad wrote:
         | He's an ubermensch to be perfectly clear - most things that
         | work for him aren't going to work or apply to the rest of us
         | because we aren't tall, white, chiseled Adonises that went to
         | Ivies and worked at Google.
         | 
         | I think most people should take the advice of experts like him
         | - people that didn't start from the bottom - with several
         | grains of salt.
        
       | karmakaze wrote:
       | This is a fine list, but not unlike many others. What I find
       | missing are the deeper elements rather than the rules of thumb or
       | general observations. Things that I find valuable after 10k+
       | hours are ways of transforming a conceptual understanding of a
       | problem into abstractions that produce a comprehensible and
       | maintainable implementation. Talking about naming variables in
       | depth alone would be more valuable than this listing, and I do
       | hope there will be follow-up posts that go in to some of these
       | points as well as cover topics that don't neatly summarize as
       | 1-liners.
        
         | rckrd wrote:
         | Great idea. Some in-depth follow ups are on my radar (I've been
         | trying to publish 1 post a day, yet, never run out of ideas.)
        
       | michaelbarton wrote:
       | Might disagree with the author on what is deliberate practice. I
       | would say the implementing code at work is not deliberate
       | practice in the sense that it's defined in the original 10k hours
       | thesis.
       | 
       | I think in the strictest sense deliberate practice is picking
       | something that you're weaker at, and spending time deliberately
       | working on that.
       | 
       | I imagine that some part of the author's 10k hours was working on
       | projects outside their comfort zone, while others were within it.
       | The argument would be doing stuff that you're comfortable with or
       | don't have to think too hard about would not be deliberate
       | practice.
        
         | rckrd wrote:
         | Agreed - tough to nail down a definition of deliberate practice
         | for software engineering. I credit three sources
         | 
         | - Working on a large open-source gave me access to high-quality
         | reviewers from around the world.
         | 
         | - Likewise, at Google, I was surrounded by some exceptionally
         | smart people.
         | 
         | - Finally, like you said, working on projects outside the scope
         | of my work and expertise.
        
           | michaelbarton wrote:
           | Thanks for your comment. I enjoyed your article. Deliberate
           | practice is something I've thought about before in the
           | context of programming and it's hard to nail down. Especially
           | because of how some of the skills are not programming at all.
           | E.g. How might you deliberately practice skills like
           | requirements gathering or managing stakeholders.
        
         | rustyminnow wrote:
         | As an R&D engineer my grandfather used to say that if you're
         | working on something new everyday for 20 years that's a lot of
         | experience. But if you're working a job you can master in a
         | year, is it actually 20 years of experience, or 1 year of
         | experience 20 times?
         | 
         | I'm not saying you're wrong - just implementing code at work by
         | itself isn't deliberate practice - but I think it can be if you
         | work just outside your comfort zone. Personally, I find work
         | incredibly dull when I'm not learning something new.
        
       | cudgy wrote:
       | 10,000 hours programming is not specific enough of a target to
       | equate to Gladwell's examples. It's like saying "I practiced
       | playing sports for 10,000 hours, so I am a professional athlete."
       | 
       | Now, if you developed using a single language targeted on a
       | specific platform for 10,000 hours while challenging yourself at
       | a high level, you would have a very strong level of expertise in
       | that area.
       | 
       | Furthermore, Gladwell made the distinction that the hours spent
       | should be deliberate and tailored to improve skills. Working on
       | tasks handed down to you by your superiors at Google is not
       | deliberate practice.
        
       | welder wrote:
       | I recently reached 10k hours too this week. (I've coded more than
       | 10k, but only tracked time for 10k) Here's my language usage for
       | those 10k hours:
       | 
       | https://twitter.com/alanhamlett/status/1423738961550184449
        
       | eeegnu wrote:
       | > 23. While rare, sometimes it's a problem with the compiler.
       | Otherwise, it's always DNS.
       | 
       | Is DNS here just referring to Domain Name System, as in to
       | reference problems with systems out of our control?
        
         | syoc wrote:
         | A lot of organizations control their own name servers. There
         | are also heaps of problems that can manifest on the client.
        
         | rckrd wrote:
         | Domain Name System - As a developer working on Kubernetes. It's
         | always DNS.
        
       | Fiahil wrote:
       | > 5. Simple is hard.
       | 
       | Yes.
        
         | Supermancho wrote:
         | Simple is easy to maintain, so this is more of an inane
         | statement. It's supposed to makes sense by reaffirming
         | something vague in the context the reader's experience. This is
         | an example of the worst kind of bullet points, pervading the
         | "learned lessons" blogspam.
        
       | 3pt14159 wrote:
       | I agree with almost all of these viewpoints. The comment one
       | though isn't quite right.
       | 
       | Sometimes you just need a comment. For example, I was writing
       | some code to an API and the company was offering a private
       | experimental feature. The API was JSON, but this one feature was
       | enabled by adding a small stringified JSON object to a field of
       | the larger JSON post body. If a developer looks at it, they'll
       | think "this must be wrong" but with a comment that briefly
       | mentions why, everyone will be saved some time.
        
         | 5faulker wrote:
         | For a larger scale one-man project, you can also use mnemonics
         | to keep track of what code's doing what, but that is unlikely
         | to work out smoothly in a team-work setting.
        
         | rzimmerman wrote:
         | Yes I agree with the sentiment, but I think long comments are
         | useful for explaining _why_ a choice was made. Or an
         | idiosyncrasy of the system like you said.
        
           | christophergs wrote:
           | This. Comments are for why.
        
             | jlc wrote:
             | IMO commit messages are for why.
        
               | jlc wrote:
               | LOL. I'm going to explain this for myself and then never
               | look at this cursed thread again.
               | 
               | What is important is to clearly communicate the intent of
               | code to the next developer (incl., yourself) who comes
               | across it. Comments are one tool provided to do this. I
               | write comments. I approve pull requests containing
               | comments. But comments are not the only tool, and they're
               | not the best one.
               | 
               | Now most of the time there's no particular difficulty
               | establishing the intent of code. Sometimes, though,
               | there's something weird, something that looks "wrong" but
               | isn't. In those cases, I isolate the weird change using
               | abstractions (at least a variable, but probably a
               | function, a method, a class); I name it and any
               | components well -- long, descriptive, using appropriate
               | conventions; I put automated tests around it, which will
               | fail if anyone changes it without understanding it,
               | providing helpful and explicit error messages (where
               | tools allow); and I write a developed, full explanation
               | in a commit message (which IME will not be too hard to
               | track down, if you've isolated the "weird" change using
               | an abstraction).
               | 
               | That will almost always communicate the the intent. If it
               | doesn't, I (reluctantly) comment it up.
        
               | Groxx wrote:
               | .... sometimes, yeah. When "why" is highly temporal, it's
               | a great fit, since that doesn't often have anything to do
               | with the code or behavior itself - put that in the commit
               | message, and/or in your ticketing system. It's a waste of
               | space and a distraction / source of confusion in code.
               | 
               | For many other things though, it's so easy to "cover up"
               | commit history. Changing how you indent things (or splay
               | one line into multiple), correcting a spelling error, etc
               | all make it _dramatically_ harder to follow than an in-
               | code comment, even with good tool support (which is
               | usually mediocre at best). Of course, you can keep those
               | changes separate, and add them to an  "ignore these
               | commits" list for git... but few teams are capable of
               | maintaining that in the long run.
               | 
               | (I assume/hope you just got downvoted in a burst of
               | emotional bikeshedding. certainly doesn't seem negative-
               | reputation-worthy to me)
        
               | nradov wrote:
               | Until a few years later when you have to move the source
               | code to a new repository or totally different source code
               | control system and lose all the commit messages. In
               | theory there should be a way to migrate the entire tree
               | and keep the commit history but in practice from what
               | I've seen that seldom happens.
        
               | isbvhodnvemrwvn wrote:
               | Or refactor something and git no longer thinks the new
               | files are related to the old one since there is too
               | little overlap.
        
               | magnusmundus wrote:
               | Do you really prefer digging through years of commit
               | messages to find why a particular line exists? It's a
               | very impractical place for those. And good luck finding
               | the origin of that line if there was an extensive
               | refactor in between.
               | 
               | Also, how do you notify a later viewer that there's a
               | "why" they should check? A comment that says "check
               | commit messages for this line"? :)
               | 
               | Not to mention: you're losing the notes as soon as you
               | move repositories, or worse, version control systems.
               | Yes, I've hit the "SVN git migrate" wall way too many
               | times. For that reason I even started leaving issue
               | numbers in comments for when it's particularly important,
               | in case we lose the commit<->ticket link down the line.
        
               | jlc wrote:
               | Typically, it isn't digging. It's the last commit, maybe
               | the one before it, and I have tools for doing this (e.g.,
               | magit, fugitive).
               | 
               | I don't notify anyone, nor do I need to. When I encounter
               | a WTF moment, I look at the commit messages. When there's
               | nothing there, I curse the last developer.
               | 
               | I guess it can be fun spelunking through commit messages,
               | though, to see when the comment was added and if it still
               | applies.
        
               | FascistDonut wrote:
               | Yeah but you (or another developer) probably won't see
               | the commit message later in the future when you come
               | across that segment of code.
        
               | andrewnc wrote:
               | I think vs code has an extension that lets you see git
               | info (committer and commit message) inline if you hover
               | over a piece of code.
        
               | ensiferum wrote:
               | Git lens
        
               | baby wrote:
               | Commit messages are the worst place for that. Someone
               | should write a post once and for all about this myth so
               | we can refer to it in the future.
        
         | taf2 wrote:
         | 10 years later I am very happy when I find I left myself a
         | little note explaining to my future self my thinking at the
         | time... more often then not though I'm left trying to remember
         | those busy days building all the shiny new things
        
           | minxomat wrote:
           | The only side projects that even have a chance of being
           | rescued from certain death are the ones my past self was kind
           | enough to explain.
        
         | rckrd wrote:
         | I agree - I think I needed to add a bit more nuance, which I
         | did in https://news.ycombinator.com/item?id=28087165
        
           | mastersummoner wrote:
           | Appreciate the clarification. Comments can (and are)
           | definitely overused and abused, but they absolutely have
           | their place.
        
         | dec0dedab0de wrote:
         | By using "should" and "probably" it's acknowledging that there
         | are exceptions.
         | 
         | Though I don't think your example is an exception. I would
         | refactor that part out to a seaprate function, and give it a
         | docstring like "json in json, because the api is weird, [link
         | to api docs]." Basically, weird things like that should be
         | refactored into their own spot, instead of called out with a
         | comment in the middle of something else.
        
           | [deleted]
        
         | [deleted]
        
         | gcmeplz wrote:
         | Even in situations like that one, I think it's possible to
         | avoid the comment:
         | 
         | - setting up a type (with a comment linking to that API's
         | documentation)
         | 
         | - setting up a shape validator & a test that asserts that that
         | that field is a string with the correct shape
         | 
         | - Using a variable name that makes it clear that something
         | intentional is happening: `const weirdlyStringifiedJSONObject =
         | JSON.stringify(...)`
         | 
         | A comment might still be the simplest thing to add, but it
         | doesn't mean it's the only way to document that weirdness.
         | Comments can be fragile compared to the same documentation
         | expressed in code
         | 
         | [edit: list formatting]
        
           | d4mi3n wrote:
           | I agree that these are all good things, but they cover the
           | what and not the why. I find design documents useful to cover
           | the why--something that results in a long comment in my
           | experience is _usually_ indicative of some non-trivial design
           | decision.
        
           | jjice wrote:
           | Those definitely work, but adding a comment is the easiest
           | and clearest way. No need to avoid comments like the plague,
           | just avoid overuse.
        
         | WalterBright wrote:
         | I find it very helpful, when implementing part of the compiler,
         | to include a link (for D) or a paragraph number (for C) that
         | references the corresponding specification section:
         | 
         | https://github.com/dlang/dmd/blob/master/src/dmd/cparse.d#L5...
         | 
         | Ever since the Intel CPU spec went online, I started doing this
         | with the code generator - providing links to the man page for
         | the instruction being used:
         | 
         | https://github.com/dlang/dmd/blob/master/src/dmd/backend/cgx...
         | 
         | And for bug fixes, reference the issue which often gives a
         | detailed explanation for why the code is a certain way:
         | 
         | https://github.com/dlang/dmd/blob/master/src/dmd/expressions...
         | 
         | Ever since I enhanced the editor I use to open the browser on
         | links, this sort of thing has proven to be very, very handy.
        
           | danuker wrote:
           | Looking at the code on GitHub, this extension may be useful:
           | https://greasyfork.org/en/scripts/2709-linkify-plus
        
             | WalterBright wrote:
             | Not needed, I fixed my editor to automagically recognize
             | URLs and make them clickable!
        
           | pm215 wrote:
           | I've done the "reference the spec section" thing before --
           | the difficulty is that often section numbers or similar
           | things get stale when a newer revision of the spec document
           | is published; so it can work for a slow-moving thing like the
           | C spec but is more awkward if the spec/manual gets a revision
           | every six months.
        
             | WalterBright wrote:
             | It's a good point. This is why for C the references are to
             | a specific standard, i.e. C11. For D, I use named links,
             | which we try to not change. The bugzilla numbers do not
             | change, which is a feature of bugzilla.
             | 
             | Even so, the utility of the links far outweighs the
             | possibility of needing to adjust them.
             | 
             | P.S. I've found using links to Microsoft documentation to
             | be extremely frustrating, because not only does Microsoft
             | move them around all the time, but will wholesale
             | permanently delete vast swaths of reference material.
             | 
             | Notice that the github links are to line numbers. Line
             | numbers are ephemeral, I don't know a way around that.
        
         | zelphirkalt wrote:
         | With comments it strongly depends on what kind of project your
         | are doing. Is it code which will run in a production
         | environment? What are the capabilities of other other people
         | working on the project? Is it a learning project, in which you
         | soak up every line and explain it for yourself and your future
         | self? Is it your own code, which you are writing? Or is it code
         | you found online and only want to comment? And comment for
         | whom? ...
         | 
         | I find especially in learning projects, where I might write
         | some quite dense code, it helps to describe what each line does
         | and answer all the "idiot questions", the ones that you can
         | answer a few minutes later or perhaps hours later with a face
         | palm, when everything is clear again, that arise, when you have
         | to cold boot your brain to pick up the project again or use the
         | code in a real project later on.
        
         | toolslive wrote:
         | sometimes a comment is needed:                  /* DO NOT
         | DELETE the above test           If you're on localhost and
         | opening/closing sockets           at high speed, you might end
         | up being connected            to yourself by accident. That's
         | what you get            when everything is a file and all files
         | are           represented with integers        */
         | 
         | For example.
        
         | zelos wrote:
         | Exactly: I think it's almost a rule that you _must_ comment
         | code that does something out of the ordinary for a good reason.
        
       | markus_zhang wrote:
       | Configuration is hard. Most of the cases I see people eventually
       | crank out their own DSL and "teach" other people to use it.
        
         | rckrd wrote:
         | Author here, ironically, guilty of this https://matt-
         | rickard.com/virgo-lang/
        
       | bluetomcat wrote:
       | For me, the most valuable insight has been to understand the
       | problem at hand with its intrinsic complexity, constraints and
       | requirements. Only then can you construct efficient and clear
       | abstractions with as little accidental complexity as possible.
       | 
       | Sometimes this can mean writing a very small amount of glue code
       | calling external libraries. Sometimes it can mean avoiding a
       | library/framework and rolling your own solution which solves a
       | specific subset of the problem, enabling a smaller footprint and
       | less dependencies. No silver bullet, really.
        
       | jdeaton wrote:
       | > If you have to write a comment that isn't a docstring, it
       | should probably be refactored.
       | 
       | Yikes. Can't read past that.
        
         | danuker wrote:
         | Instead of a comment informing a user how something works (or
         | how something does not work), write a test demonstrating and
         | documenting its use.
         | 
         | The test will not forget, and has a docstring explaining what
         | and why.
         | 
         | But crucially, it is automated, and does not rely on mistake-
         | prone humans to check (as is the case of a comment).
        
       | moonchrome wrote:
       | >In many cases, what you're working on doesn't have an answer on
       | the internet.
       | 
       | >That usually means the problem is hard or important, or both.
       | 
       | Really ? If a problem is important someone likely already tackled
       | it. I mean 15 years ago this was less likely, but these days
       | there's so much work in the open and search is very good, when I
       | find there aren't any references for my problem it usually means
       | I misinterpreted the problem or I'm doing something very niche.
        
         | mrweasel wrote:
         | I feel like your argument is a little along the line of: "
         | Everything that can be Invented has been Invented"
        
           | moonchrome wrote:
           | No, just that CS/programming is mature enough that important
           | stuff has already been explored so if I'm hitting a dead end
           | either I'm doing something very specific that hasn't been
           | investigated yet or (more likely) I'm not framing the problem
           | correctly.
        
         | rckrd wrote:
         | You're implying the reverse causation. The reflection is "can't
         | find answer" -> "might be hard", not "might be hard" -> "can't
         | find answer".
         | 
         | Surely there is copius documentation on a significant number of
         | hard problems.
        
         | tonymet wrote:
         | When you get above the 40th percentile in problem difficulty or
         | novelty, there are no answers or even discussions on the
         | internet.
        
       | martinhath wrote:
       | Good post, and a good list. Here's a mind dump on some of the
       | items:
       | 
       | Right off the bat:
       | 
       | > Well, I'm certainly not a world-class expert, but I have put my
       | 10,000 hours of deliberate practice into programming.
       | 
       | Okay, I don't know the authors exact history here, but I
       | _seriously_ doubt that they 've had anything that's even close to
       | 10k hours of _deliberate practice_ of programming. Why? Because
       | programmers basically  /never/ do any deliberate practice. We
       | don't have anything that's even close to what a piano player does
       | when they practice fingersetting, chord transition, scales, or
       | the like. I'm not even sure what this would look like, but I
       | suspect that it is fundamentally different. Most musical
       | instruments have a physical or mechanical side to them that is
       | completely disjoint from the "musical" part of it. For instance
       | knowing how to play a cool solo a guitar (meaning knowing which
       | notes to pick and how long to hold them for), and being able to
       | have your left hand fingers in the right positions in the right
       | times and your right hand picking the right strings has almost
       | nothing to do with each other. The way it usually works (I'm an
       | amateur player who hasn't played in years, so maybe some
       | professionals can take over this analogy) is that you practice
       | very slowly and ramp up quicker and quicker untill "magically"
       | your muscle memory takes over and it all kind of just happens.
       | The result is that you don't really pick each indivitual note
       | anymore, you kinda just play that part (when practicing you've
       | decomposed the whole piece into small parts), and each part is
       | atomic to you. Starting in the middle of a part doesn't quite
       | work.
       | 
       | The only programming analogy I can think of (from the top of my
       | head) is how effortless it feels to write `for (int i = 0; i < n;
       | i++)`, or something like it. But we only spend a negligible time
       | on actually writing out the lines of code when programming, so
       | while being able to effortlessly write out a bunch of standard
       | `for` loops doesn't really push the needle in any way. For a
       | performing musicial, of course, this is very different, because
       | the /have/ to play it right! Imagine having to write all your
       | `for` loops in sync with the beat of music.
       | 
       | > 4. Syntactic sugar is usually bad.
       | 
       | It's hard to really get exactly what this means, because if taken
       | literally it is obviously not true. Pretty much any loop or
       | control flow structure is just syntax over goto, but I assume the
       | author doesn't really think we should manually write out the
       | gotos. Having recognizable patterns in a codebase is good.
       | Cramming in some esoteric syntax quirk of your language into your
       | code because it technically fits is not good.
       | 
       | > 5. Simple is hard.
       | 
       | Again, difficult to get something concrete out of this since it
       | reads as a zen mantra. If they mean that finding a simple
       | solution to a difficult problem is hard then I agree. If they
       | mean that a system being simple means it is hard to use then I
       | disagree.
       | 
       | > 7. Know the internals of the most used ones like git and bash
       | (I can get out of the most gnarly git rebase or merge).
       | 
       | Knowing the _internals_ of e.g. `bash` is too far for me. I 'm
       | happy if I even knowing the surface of it! I guess they mean that
       | cargo culting these tools usually doesn't lead you anywhere good
       | and that invesing the time into them will pay off, as opposed to
       | "cookbooking" it, like with git in that xkcd.
       | 
       | > 9. Only learn from the best. So when I was learning Go, I read
       | the standard library.
       | 
       | I think this is important, but it is very difficult for
       | programmers to do this,
       | 
       | > 10. If it looks ugly, it is most likely a terrible mistake.
       | 
       | I don't think this is good advice because it suggests that all
       | code should "look nice" and if it doesn't it's just wrong. In my
       | experience the number one metric (if you can even call it that)
       | one should be concerned about is flexibility. If your code is
       | "rigid" and difficult to change it really doesn't matter a whole
       | lot how nice it looks, because, presumably, you're not really
       | sure exactly what you're doing, and the code you write will
       | probably not last very long in the codebase. It's hard to put a
       | number on this, but I'm pretty sure most of the code I write does
       | not last a month. All the time I'd spend worrying about whether
       | this code was "ugly" is effectively wasted, because in a month it
       | will not exist any more. Make code easy to replace.
       | 
       | > 11. If you have to write a comment that isn't a docstring, it
       | should probably be refactored.
       | 
       | I also don't agree with this. I think it's completely reasonable
       | to have comments in function bodies expalining what this part of
       | the function does. See Jon Blow's related blog post[0].
       | Docstrings are for users of a function, but you might also want
       | comments for the people reading the function body. Sometimes this
       | can be avoided by writing Good Code, sometimes not.
       | 
       | > 12. If you don't understand how your program runs in
       | production, you don't understand the program itself.
       | 
       | Very true; I'd phrase it as "understanding the problem", in Mike
       | Acton lingo [1]. If you don't understand The Problem, then you
       | don't understand what your program, which is (a part of) the
       | solution to The Problem, does either.
       | 
       | > 14, 15, 16
       | 
       | This is good advice, and I imagine it's difficult for beginners
       | (or novices) to make sense of what to do here; some circles
       | advocate for always pulling in dependencies, others for always
       | inlining 3rd party trees in your own codebase. I actually think
       | this is one of the parts of programming as a field that has the
       | potential for some kind of a paradigm shift. I'm not convinced
       | that in 25 years we'll be still trying to write generic
       | "libraries" for others to use, and other people will download
       | semvers of libraries to ensure compatibility. There has to be a
       | better way.
       | 
       | > 17. Know when to break the rules. For rules like "don't repeat
       | yourself,"
       | 
       | Thank you! DRY is probably the worst of the n-letter programming
       | mantras. DO repeat yourself! Do whatever you need to quickly get
       | a better understanding of your problem!
       | 
       | > 18. Organizing your code into modules, packages, and functions
       | is important. Knowing where API boundaries will materialize is an
       | art.
       | 
       | This is also very true. Given an API, filling in the function
       | bodies is often close to trivial, and coming up with the API in
       | the first place is indeed an art.
       | 
       | [0]: http://number-
       | none.com/blow/blog/programming/2014/09/26/carm...
       | 
       | [1]: https://www.youtube.com/watch?v=rX0ItVEVjHc
        
         | nodejs_rulez_1 wrote:
         | Don't learn internals of git it's a waste of time. If you feel
         | you need to learn internals of a tool then it's not a good
         | tool.
        
           | liuliu wrote:
           | I thought that "internals" means read the Git code and
           | understand how each module interacts. In that case, it is
           | probably a waste of time unless you are really passionate
           | about it.
           | 
           | I would just phrase it as "understand the tools' fundamental
           | concepts and philosophy really well".
        
         | igouy wrote:
         | > Okay, I don't know the authors exact history here, but I
         | seriously doubt that they've had anything that's even close to
         | 10k hours of deliberate practice of programming.
         | 
         | Yes.
         | 
         | 10,000 hours of code kata might be "10,000 hours of deliberate
         | practice".
         | 
         | http://codekata.com/
         | 
         | And in-any-case "Malcolm Gladwell got us wrong: Our research
         | was key to the 10,000-hour rule, but here's what got
         | oversimplified"
         | 
         | https://www.salon.com/2016/04/10/malcolm_gladwell_got_us_wro...
        
           | Zababa wrote:
           | I don't think that's true. As software engineers, our job is
           | to create working software that fits the needs of the
           | clients. Raw coding is a part of that of that, but not the
           | only one. Collaboration is important, knowing your tools is
           | important, talking to people is important.
           | 
           | Code kata are a good example of people trying to stretch
           | metaphors from other domains to fit software engineering. It
           | usually doesn't really work. For athletes and musicians, the
           | "performance" part is a small part (in terms of time) of
           | their job. They spend way more time training. For software
           | engineers, that's not the case. There is a spectrum of things
           | more or less important, for sure, but nothing as clear cut as
           | with music or sports.
           | 
           | The difference between deliberate practice and "mindless
           | practice" is usually using a moment to reflect on what you
           | did, and how things went. In scrum, this is often the sprint
           | review. So by that definition, if you do your sprint review
           | correctly, you're doing at least some form of deliberate
           | practice. Same thing with code reviews, you have the
           | opportunity to have other people look at your code and
           | evaluate it. You can of course add to that your own for of
           | review. But in general, as a industry, I'd say we're very
           | focused on practicing on the job.
        
       | rckrd wrote:
       | Author here, thanks for posting.
       | 
       | Here's some more color on the reflection on comments, straight
       | from the Linux Kernel documentation that capture my intention
       | much better:
       | 
       |  _" Comments are good, but there is also a danger of over-
       | commenting. NEVER try to explain HOW your code works in a
       | comment: it's much better to write the code so that the working
       | is obvious, and it's a waste of time to explain badly written
       | code.
       | 
       | Generally, you want your comments to tell WHAT your code does,
       | not HOW. Also, try to avoid putting comments inside a function
       | body: if the function is so complex that you need to separately
       | comment parts of it, you should probably go back to chapter 6 for
       | a while. You can make small comments to note or warn about
       | something particularly clever (or ugly), but try to avoid excess.
       | Instead, put the comments at the head of the function, telling
       | people what it does, and possibly WHY it does it."_[0]
       | 
       | [0] https://www.kernel.org/doc/html/v4.10/process/coding-
       | style.h...
        
         | Clubber wrote:
         | The best comments are about intent. I can read the code and
         | tell you what it does, but I have no idea if that's what it's
         | _supposed_ to do without knowing the intent.
        
         | jbverschoor wrote:
         | Don't agree. Longer pieces of code are way easier to reason
         | about. Deep function nesting, which seems clean is very
         | confusing mentally, and also difficult to describe in terms of
         | function name.
         | 
         | Explain *why* you're doing something a certain way. This also
         | includes a little bit of how and what. Other than that, just
         | make sure your business terms are reflected in the code, or at
         | least have a proper definition of things, which you can easily
         | reason about.
        
           | bcrosby95 wrote:
           | I've always felt like this is where IDEs could help. You
           | should be able to "inline" the implementation of a function
           | or even whole class without actually changing the code.
        
           | LouisSayers wrote:
           | They may be easier in some cases to reason about - which is
           | great until you start writing tests.
           | 
           | Once you start writing tests you find that the size of test
           | functions will reflect the size of the function you're
           | testing. The test functions start to have huge set-ups in
           | order to test a small bit of logic, and you end up spending a
           | lot of time fixing tests every time you make a change to that
           | function.
           | 
           | This is why it's often better to find ways to make functions
           | smaller.
           | 
           | There is a difference however of people refactoring code into
           | smaller classes / functions vs what I'd call "hiding" code in
           | classes / functions. If all someone has done is broken a
           | large function into a chain of functions then of course that
           | is not good.
           | 
           | When people refer to small functions / classes they refer to
           | breaking up the concepts that a class / function represents
           | into smaller concepts that build upon one another. This also
           | increases the reusability of code.
           | 
           | So in short - I agree, longer pieces of code can be better
           | for reasoning about, but I disagree that that necessarily
           | makes them better.
        
           | jcelerier wrote:
           | Eh, to each their mental models. I have much less trouble
           | understanding nested and, some may say, very-class-segregated
           | code than mostly procedural one as the general shape of the
           | code + the pattern names used generally gets me 95% of where
           | I have to be to understand what is the issue at hand. But
           | then I found out that not a lot of people draw diagrams when
           | they are coding ? (Which in my case helps immensely - and
           | after some time you can just draw the diagram in your head)
        
           | cudgy wrote:
           | Agreed. When looking at complex code, it can be helpful to
           | expand the functions inline to be able to view all of it in a
           | single screen flow. Switching between too many files and
           | functions sometimes creates friction, making it more
           | difficult.
           | 
           | However, when writing the code if a section of code is
           | repeated more than 2 times, it should be considered to break
           | it out into a separate function with a useful name.
        
         | Retric wrote:
         | The exception to the WHAT/HOW divide is working around a 3rd
         | party bug. Documenting workarounds can help prevent
         | reintroducing the same bug when someone edits or copies the
         | code. This can be especially helpful if the 3rd party bug gets
         | fixed in such a way that your workaround now fails.
        
         | ajuc wrote:
         | > NEVER try to explain HOW your code works in a comment
         | 
         | Never is a strong word, sometimes the algorithm is just
         | inherently complex and it's worth it to explain what you are
         | doing.
         | 
         | Why is much more important, but it's also partially solved
         | automatically by git blame and adding the task number to each
         | commit message (and writing good commit messages which IMHO is
         | more important than writing good comments). Each line of your
         | code has commit message associated with it whether you care
         | about it or not - make it useful.
        
           | chris37879 wrote:
           | This is generally how I treat comments, docblocks on
           | everything for api documentation, but inside functions, yeah,
           | something clever or non-obvious gets a comment. I also tend
           | to document complex interfaces / abstract classes more
           | heavily to give people a sort of road map for implementing
           | it.
        
           | bccdee wrote:
           | Yeah algorithms in particular are where I'm hesitant to say
           | "never explain how your code works." They can be dense,
           | deeply-nested, and hard to break down into semantically-
           | meaningful variables and function names. Sometimes it's good
           | to explain what's going on there.
        
           | cjohansson wrote:
           | Yeah the how is important when auditing the correctness of
           | code. I would say "Never listen to an advice about never
           | doing something, there is always a case were breaking the
           | rules is good"
        
             | [deleted]
        
           | vhakulinen wrote:
           | From the linked post:
           | 
           | > Know when to break the rules.
        
         | 908B64B197 wrote:
         | > tell WHAT your code does, not HOW
         | 
         | And also Why.
         | 
         | I personally like an executive summary of the code, ie, I just
         | got to this file, what am-I looking at.
        
         | franciscop wrote:
         | Small typo, it's "Malcolm Gladwell in Outliers" not
         | "Outsiders", I particularly noted it because I learned the word
         | "outliers" in English thanks to that book.
        
           | rckrd wrote:
           | Thanks, fixed!
        
         | juancb wrote:
         | What's your take on the difference between explaining how code
         | works and describing what it does?
         | 
         | I only ask because of bits like the TCP rate estimator
         | sometimes have step by step comments that might be interpreted
         | as explaining how the code is doing something.
         | 
         | For example take the app limited detection function:
         | https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_r...
        
           | mastersummoner wrote:
           | My take is that step by step commented explanations make
           | sense when it's something either extremely complicated or
           | making use of a system or tech that's not widely known.
           | 
           | Otherwise, clearer code, smaller methods and better
           | variable/method names are the way to go imo.
        
         | baconforce wrote:
         | I've seen this interpreted by smart engineers in a counter-
         | productive way, in that they believe their code is so good that
         | none of it ever needs any comments and hence they never write
         | them despite the fact that their code isn't all that clear.
         | It's more hubris than anything.
         | 
         | Otherwise, there are many techniques you can use to make the
         | code self-explanatory. I've taken a comment before and
         | restructured the code to literally read like the comment.
        
         | dnautics wrote:
         | I think sometimes you want to put _why_ in a comment. Just
         | today I wrote a two paragraph comment (usually I don 't write
         | many comments at all) that describe the business need for why
         | this the code is necessary (in my case, connecting to a 3rd
         | party data source that overshares, describing the nature of the
         | oversharing, outlining the -- very complex -- steps in the
         | pruning algorithm, and noting that there are corner cases we
         | might miss and also noting that we shouldn't care -- a handful
         | of bad apples in a machine learning algo will probably
         | disappear in the wash).
        
         | hutzlibu wrote:
         | I prefer over-commenting a lot, over under-commenting.
         | 
         | The only harm is, when you miss the important bits over too
         | much blabla, or when you forget to update comments. There are
         | not many worse things, than wrong documentation/comments.
         | 
         | "you want your comments to tell WHAT your code does, not HOW"
         | but I agree very much to this.
        
         | efsavage wrote:
         | The WHY is also very useful in comments, especially in
         | business/UI/glue code where special cases abound.
        
           | klysm wrote:
           | I would say the why might be more important than the what a
           | lot of the time
        
           | david-gpu wrote:
           | Came here to comment along those lines.
           | 
           | The WHY often will be elaborate enough that it deserves a
           | design document that includes things like: who is the owner
           | of those requisites, what is the rationale behind them, who
           | are the stakehilders who signed off, what interactions it has
           | other components, what alternative designs were considered,
           | etc.
        
         | rgrmrts wrote:
         | Interesting reading about RuneScape in your post. I got into
         | programming because of RuneScape and writing bots! Great
         | memories.
         | 
         | I enjoyed reading this post. Cheers!
        
           | AQuantized wrote:
           | Writing increasingly sophisticated bots and trying to figure
           | out what exactly would earn you a ban was my own first
           | practical experience with coding.
           | 
           | I mostly managed to dodge bans on my most used accounts at
           | the time, but interestingly when I checked back a year or two
           | ago the majority had been permanently suspended. I wonder if
           | they have some method of retroactively determining if someone
           | was botting?
        
           | rckrd wrote:
           | Thanks! Likewise. Truly a great sandbox for budding
           | programmers.
        
             | mastersummoner wrote:
             | I got into programming at 14 because of writing scripts in
             | Gemstone, a text based MMOMUD. Didn't even realize what I
             | was doing was programming until college though...
        
               | calrizien wrote:
               | Gemstone! That game changed everything for me
        
         | baby wrote:
         | > try to avoid putting comments inside a function body
         | 
         | This makes me sad. Think about others who will have to reverse
         | engineer your code. Not every functionality should be split
         | into a function, unless you want to add 10 layers of
         | abstraction and misdirection.
        
         | mastersummoner wrote:
         | Another reasonable exception is referencing external sources -
         | whether it's a specific library you borrowed code from, a piece
         | of documentation needed to better understand what's going on,
         | or a reference to a SO post explaining some weird workaround
         | you've implemented.
        
       | __hjf wrote:
       | This is a great read. Posts like this make me not fear being
       | "just a developer" for the rest of my life.
        
         | rckrd wrote:
         | Software engineering is one of the highest leverage things you
         | can do. Keep it up!
        
       | edumucelli wrote:
       | Too many of the items are deeply influenced by Golang principles
       | or quotes I have seen from Gophers. I think this is a very
       | interesting Go-oriented reflections on 10k hours of programming.
       | 
       | I think it boils down to each 10k hours of programming on (or
       | mostly on) a certain language will give your different
       | reflections that we think are general.
        
       | rajasimon wrote:
       | I don't understand the 11'th one can someone explain to me also
       | the given link seems broken.
       | 
       | > If you have to write a comment that isn't a docstring, it
       | should probably be refactored. Every new line of comments
       | increases this probability. (For a more nuanced take, the Linux
       | Kernel Documentation)
        
         | rckrd wrote:
         | Link should be fixed. It's
         | https://www.kernel.org/doc/html/v4.10/process/coding-style.h...
        
         | tudelo wrote:
         | One way that I was taught is via the HTDP "design contract". So
         | in this case a "docstring" translates to defining the method
         | contact (its inputs and outputs) and the purpose of the
         | function (what the function does).
         | 
         | https://course.ccs.neu.edu/csg107/design-recipe.html is a
         | random link that describes all the steps, with something like
         | 2. being the one mentioned (I think, I'm not OP.)
        
         | adamnemecek wrote:
         | He means that you should avoid commenting single lines but
         | instead write comments on whole functions.
        
       | BatFastard wrote:
       | Reflections on 40k hours of programming. Developers are a pain in
       | the ass. But I still love making things work!
        
       | azangru wrote:
       | > Well, I'm certainly not a world-class expert
       | 
       | > Most recently, I worked as a professional software engineer at
       | Google on Kubernetes
       | 
       | If this is not a world-class expert, who is?
        
         | [deleted]
        
         | mgkimsal wrote:
         | ... "which allowed me to have my code peer-reviewed by some of
         | the best engineers."
         | 
         | The "I'm not an expert" mindset probably comes from working
         | with many other people who, collectively, are certainly 'more
         | expert' than the single author.
        
       | carlisle_ wrote:
       | >Know when to break the rules. For rules like "don't repeat
       | yourself," sometimes a little repetition is better than a bit of
       | dependency.
       | 
       | Glad to see DRY called out here. I've seen so much crazy code
       | simply to avoid breaking, The Rule.
        
         | ctvo wrote:
         | Trade-offs are the heart of this profession. Developers who
         | stick blindly to DRY, SOLID, any dogma really, come off as
         | inexperienced.
        
         | franciscop wrote:
         | Same here, furthermore I've written so much crazy code early on
         | to avoid breaking The Rule, looking back I'm double horrified;
         | at what I did, and knowing that a lot of junior programmers are
         | going through that phase now.
        
         | Jtsummers wrote:
         | What's frustrating is that DRY is often paired with something
         | like "The Rule of Three". _Do_ repeat yourself about three
         | times until you actually understand what it is that 's being
         | repeated (or whether it's just coincidental) so it can be
         | refactored. But a lot of people forget that part and focus only
         | on DRY.
         | 
         | Is the magic number 1024 the same in all instances, for
         | example. Or is it merely a coincidence that it's the same in a
         | few places. Is the apparently repetitious code:
         | context = create_context();       context.action(params);
         | 
         | In several places _really_ the same? Or is it a coincidence
         | that _right now_ none of them pass any parameters to
         | _create_context_ and use the same params in their call to
         | _action_?
         | 
         | Avoiding the repetition makes it hard to even ask that
         | question. And disentangling the different cases later is
         | riskier than keeping a few pieces of repeated code around for a
         | while to understand the situation better.
        
           | jaredsohn wrote:
           | Instead of calling it 'The Rule of Three', call it WET (Write
           | Everything Twice); makes it easier to remember (although I
           | think that is one less repetition than suggested in the
           | parent.)
        
             | lucasmelin wrote:
             | In that case, you could keep the acronym the same, but just
             | explain it as Write Everything Thrice.
        
             | louthy wrote:
             | The problem isn't the acronym, it's the dogma that grows
             | around it. WET will be wrong in certain circumstances too.
             | 
             | Our industry is full of dogma and false prophets. It's
             | unbelievably frustrating.
        
               | jaredsohn wrote:
               | Nobody should always DRY or WET; my context is I wrote
               | some code for a greenfield part of a project and was told
               | to DRY multiple times. Was easy to reply 'I prefer WET
               | here' and link to an article on WET rather than
               | explaining the redundancy.
               | 
               | Interestingly, I just looked at the wikipedia page for
               | DRY
               | (https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
               | and see they also mention another acronym - AHA (avoid
               | hasty abstractions); I might use that in the future.
        
               | [deleted]
        
             | Jtsummers wrote:
             | The name is largely irrelevant, though WET may be more
             | memorable when attached to DRY. The important element is
             | the deliberate introduction or allowance of repetition with
             | the intent (and ideally actually doing) of examining and
             | refactoring later. Later is often not even that much later,
             | IME. Usually the next step I take after putting in the
             | repetition because I can see the common structure properly
             | while it's all fresh in my head, but I couldn't see it when
             | I initially started writing it (or saw the wrong part as
             | the common structure, which bit me enough that I committed
             | to the rule of three idea).
        
             | imilk wrote:
             | just stay MOIST and you're gravy
        
             | [deleted]
        
             | semitones wrote:
             | Write Everything Thrice?
        
         | brundolf wrote:
         | I like WET: "Write Everything Twice [before factoring it out]"
        
         | BeetleB wrote:
         | Every few months there is a comment complaining about DRY, and
         | a counter comment complaining about misunderstanding of DRY. So
         | allow me:
         | 
         | DRY originated from _The Pragmatic Programmer_ , and is _not_
         | about avoiding duplicated code. In fact, quite a bit of
         | duplicated code doesn 't break the DRY rule as originally
         | defined.
         | 
         | If I make my own list, I'll be sure to put "Understand what DRY
         | is before complaining about it." :-)
        
           | dllthomas wrote:
           | We should refer to removal of accidental syntactic repetition
           | because of an overapplication of misunderstood "DRY" as
           | "Huffman coding."
        
       | mastersummoner wrote:
       | I will say, I think the one point in this article I disagree with
       | is about finding answers on the internet. There are certainly
       | been many times I've needed to dig into the source of something
       | I'm working on, but much more often than not I've been able to
       | find an exact (or close enough) answer with a couple of different
       | Google searches.
       | 
       | Granted, this may be because the areas I work in are less
       | technically complex than, say, writing low-level code or IoT
       | instructions.
        
       | GnarfGnarf wrote:
       | 10K hours??! Try 100K hours (55 years x 50 wks/yr x 40 hrs/wk).
       | 
       | I still don't know much.
        
         | otagekki wrote:
         | What would you expect to be able to do after 100k? Coding and
         | debugging any codebase in any of the 10 most used languages
         | without internet? God knows if I'll still be alive after 55
         | years
        
       | skohan wrote:
       | > Syntactic sugar is usually bad.
       | 
       | I disagree with this one. It _can_ be bad, but if it helps syntax
       | get out of the way to reveal the intent of your code, I think it
       | 's pretty good
        
         | ithinkso wrote:
         | I'm actually on the opposite side of this. I know HN is more
         | web-focused so embedded isn't as much represented but I'm
         | scared every time I'm trying to learn Javascript or even Rust.
         | 
         | Syntactic sugar complicates code for me, it may help to reveal
         | the intent what the code is doing but I *have to* know how the
         | code is doing it. Of course you can just learn what the
         | compiler will do in every of those instances but that's a lot
         | to learn and it increases exponentially. On the other hand in C
         | you have assignments, conditionals, loops and function calls -
         | nothing else.
         | 
         | In the end the code will do the same thing but I'm willing to
         | spent few more keystrokes and maybe an added comment just for
         | the peace of mind of knowing what is actually happening. (One
         | may say that the assembler output is still a blackbox but the
         | general structure of the computation will remain intact)
         | 
         | It may be outdated, I agree, but it's just something I can't
         | shake off
        
           | mastersummoner wrote:
           | Any thoughts on Ruby? As someone who's worked with it a great
           | deal of the time, I find it extremely simple and concise to
           | write in.
        
             | ithinkso wrote:
             | I haven't tried Ruby at all to be honest. If I need to do
             | some quick'n'dirty scratchpad calculations on x86 I'm using
             | python but I find myself still using 'C-like' approach
             | instead of idiomatic python. I.e. even 'for x in X:' gives
             | me heebie-jeebies for some unexplained reason (though I use
             | it). I think it's because I've been conditioned for so many
             | years to think about data/code as just that, data in
             | memory. So every time I need to access something I'm
             | thinking *where* it is first, not about getting it - that's
             | secondary and, paradoxically, unimportant. I'll use it in
             | the next stage/line but by then I already have it (I don't
             | know if that makes any sense at all).
             | 
             | It makes no sense to do it most of the time in most
             | circumstances, and I think downvotes I'm getting represent
             | that (though I'm not preaching it or anything, just
             | commenting about my point of view), but if you have a hard
             | deadline of X cycles you think about code differently.
        
               | milesvp wrote:
               | I totally understand. Having recently transitioned to
               | embedded C/C++, I can tell you that the way I think about
               | memory and memory access in this world is _very_
               | different than my thinking about it in python for over a
               | decade. I _really_ like iterators, they help eliminate a
               | whole class of bugs, but after the last couple of years,
               | I 'm not sure I'd be so comfortable with them if I'd been
               | counting cycles for most of my career as well.
        
               | ithinkso wrote:
               | > I can tell you that the way I think about memory and
               | memory access in this world is very different than my
               | thinking about it in python for over a decade
               | 
               | Would you be able to shed some more light on this in the
               | opposite direction? I would appreciate it because I'm
               | moving to a higher role and I would like to develop tools
               | my team can use to streamline development but I can't
               | implement them myself and I'm very anxious to take over
               | the tools team because my brain is wired in a very
               | different way (I know what they need but not how it
               | should be written) and what I think is important is
               | probably last year's snow there so I'll be slowing down
               | things unnecessarily. Any advice?
        
               | milesvp wrote:
               | If I understand you correctly, the main difference is to
               | stop thinking in terms of bits and bytes and think more
               | in terms of amorphous data. Like, for x in X: is really
               | more appropriately expressed as for value in values:
               | 
               | Values is just a container, and we'd like to grab one of
               | what it contains one at a time to do something with it
               | (I'm assuming native English speaking here, other
               | language's pluralization might not be as natural to this
               | convention). It might even make sense to start with some
               | kind of notation like, for value in valueList:, to help
               | internalize, but this can be a crutch. Because of the
               | ducktyping nature of python, values might be a list
               | today, but the same code can easily handle any iterable
               | (I've done enough maintenance programming where it was
               | clear some variable had never been renamed, it was once a
               | list, and was now something else. Type annotations on
               | newer codebases help here). The other thing to realize,
               | is that heterogeneous collections is one of the things
               | that Python excels at, and something that is likely to
               | make your head hurt in C (I'm not even sure how I'd
               | implement mixed type arrays in C without doing something
               | gross with void*). I'm not saying you necessarily want to
               | mix types since it can often lead to a bad time, but it
               | still helps to think about just how amorphous the data
               | can be.
               | 
               | Another thing that will feel really gross, is that Python
               | is going to be orders of magnitude slower than your used
               | to in C (with similar memory bloat). Just get over that,
               | and know that if you absolutely need to speed up parts of
               | the code, you can write those parts in C fairly easily.
               | 
               | Anyways, good luck.
        
           | Orou wrote:
           | If you're used to writing embedded code then I'm not
           | surprised - you want to be able to fully introspect
           | everything that is happening since understanding performance
           | is so important.
           | 
           | Syntactic sugar is often better in high-level languages
           | _because_ it provides a level of indirection and allows for
           | more flexibility in API design.
        
           | skohan wrote:
           | Idk I understand what you are saying, but in my experience
           | you just end up building an intuition around what the sugar
           | is doing, and you can de-sugar mentally to understand about
           | what the code compiles down to. But I can understand if
           | you're really working on HPC or something like that how you
           | would want to make it completely unambiguous.
           | 
           | With Rust I think it can be a bit tricky, because a lot of it
           | is context dependent, and the compiler will often make a lot
           | of things easier for you until it can't, at which point the
           | error which got you into a situation may be pretty far from
           | the code you just changed. That's why I think syntactic sugar
           | is best when it's quite dumb and local. I.e. X is just
           | another way of writing Y.
        
             | ithinkso wrote:
             | > a lot of it is context dependent
             | 
             | I think you nailed it here what I couldn't put in words. I
             | don't mind context-dependency when it's in the code I'm
             | writing (calltree, variables, flags etc.) but for some
             | reason if it's context-dependent in the language itself,
             | hidden from me, it feels uncomfortable because I cannot
             | change it, have to learn it and then have to debug it.
        
               | ithinkso wrote:
               | I've been thinking about it a bit more and I think I've
               | gotten to the bottom of the point I'm trying to make. But
               | again, it's very subtle and unimportant 99% of time but
               | it's the way I tend to think about code
               | 
               | First example (C):
               | 
               | for(i=0; i<N ;i++) { t = data[i]; ... }
               | 
               | Second example (python):
               | 
               | for t in data: ...
               | 
               | The difference is that in the second example I'm telling
               | the compiler what I want to *have*. It will give me
               | exactly that ('t' will contain consecutive values from
               | 'data') and it will do it's best automagically. In the
               | first example however, I'm telling the compiler what to
               | *do* and it will just and only follow orders (iterate
               | 'i', copy the value from data+i to 't').
               | 
               | Insignificant difference most of the time but an
               | important one to me. And sugar makes it more complicated
               | to distinguish what I told the compiler to do vs. what I
               | wanted to have. Helps me with debugging and getting cycle
               | count under control
        
           | 0xb0565e487 wrote:
           | It complicates code until it makes it easier, sometimes.
        
         | jbverschoor wrote:
         | C is just syntax sugar on top of asm.
         | 
         | We can go on and on. Syntax sugar is a compiler-level of
         | abstraction.
         | 
         | It's good
        
         | taneq wrote:
         | I see it as a language/api/environment smell, but also
         | sometimes pragmatic. A good example would be the old MFC -
         | somewhere between 'not ergonomic' and 'ungodly mess' if you
         | were using it manually, but paired with VC++ 5.0 it was pretty
         | good for bashing out general business and productivity apps.
        
         | rckrd wrote:
         | Yes, maybe usually was too strong of a word - I think this
         | varies with the language. In Go and JavaScript (where I mostly
         | work), it's usually not that useful.
         | 
         | In languages like C# and Java, I've found syntactic sugar to be
         | very useful (e.g. lambda notion)
        
           | silviot wrote:
           | I'm under the impression that, in Javascript,
           | 
           | > async/await is syntactic sugar on top of the promises and
           | provides a way to handle the asynchronous tasks in a
           | synchronous manner.
           | 
           | as is stated on this website I just found with one second of
           | googling to support my thesis:
           | https://dmitripavlutin.com/javascript-async-await/
           | 
           | If that is true, I believe it's incredibly useful syntactic
           | sugar.
        
             | rckrd wrote:
             | Fair enough, there are clearly lots of useful syntactic
             | shortcuts. I'm referring to things like prefix/postfix
             | increment/decrement, object spreading vs. object rest, and
             | ternary expressions.
             | 
             | I'd avoid cases where extending the language is done in a
             | non-obvious and ambiguous way.
        
               | dfee wrote:
               | I love me some spread operators and ternary expressions.
               | 
               | ...mumbles something about prying those from my cold dead
               | hands.
        
               | skohan wrote:
               | Yeah I think there's a time and a place for ternaries,
               | but when used correctly they're just so concise.
               | 
               | Like if you have super long expressions in your
               | ternaries, or you have a bunch of nested/chained
               | ternaries it can be hard to parse, but in a lot of cases
               | it's so nice to get something onto one line instead of
               | needing an if/else
        
               | ensiferum wrote:
               | Yes in c/++ it also allows you to use const.
               | 
               | const foo = bar ? 1 : 2;
               | 
               | Without ternary you wouldn't be able to use const
               | specifier on foo.
        
               | mjcohen wrote:
               | Love the ternary operator in gawk. Here's some extreme
               | examples, from a text formatter I wrote over 20 years
               | ago. It is over 6,000 lines of awk, and I haven't used it
               | in over 15 years.
               | 
               | Note: These lines should be split, but many of them are
               | not. How do I do that? I read formatdoc, but that did not
               | help.
               | 
               | ; # see where text starts; mut = ((substr($0,
               | lf1-length(lf1str), length(lf1str)) != lf1str) \ ? 1 \ :
               | ((substr($0, lf1, 1) == " " ) \ ? (lf1+1) \ : lf1) \ ); #
               | start of string;
               | 
               | ---------------------------
               | 
               | # return file and line number with optional text;
               | function filineg(ffilename, ffilerec, fltext) { ; # first
               | version always gives a line number, second does not for
               | line 1; return (ffilename \ (ffilerec == "" ? "" : (":"
               | ffilerec)) \ ((fltext == "") \ ? "" \ : (" in \"" fltext
               | "\"") \ )); }
               | 
               | ------------------------------------
               | outstr[2] = (head \             ( (lnum > 1) \
               | ? (substr(bigsep, 2, lnum-1) " ") \              :
               | (substr(spaces, 1, lnum)) \              ) \
               | (header2==""?" ":header2) null("output space if null -
               | 5-20-98")  \             substr(bigsep, 1, \
               | ltocout-lhead-lpn-1 \             -(lheader-
               | lheadchop)-lnum \             -((null_loc > 0) \
               | ? lnullstring \         : 0 \               ) \
               | ) " " pn); # parens make it line up;
               | 
               | ----------------------
               | 
               | function telldepth(deptxt, dep1, dep2) { ; # change depth
               | from dep1 to dep2; ; # good luck figuring this out in a
               | month!; ; # tell how depth changes; recnumprint("{"
               | deptxt " " \ ((dep1=="") \ ? ((dep2=="") \ ? ("leaves
               | depth as is") \ : ("sets depth " dep2)\ ) \ : ("changes
               | depth " dep1 " to " dep2) \ ) " in " filine() "}"); }
        
               | frosted-flakes wrote:
               | Prepend each line with two spaces to format it like code.
        
               | mastersummoner wrote:
               | I have to say, I really love the back and forth between
               | you and the various posters in this thread. Lots of good
               | discussion and points being made, and reasonable
               | compromises being agreed on - or even polite disagreement
               | with thoughtful explanations why.
        
           | ajuc wrote:
           | Lambda isn't syntactic sugar, it's a language feature.
           | 
           | In Java it's kind of a syntactic sugar (lambda is a shortcut
           | for an anonymous class with 1 method) because of historic
           | reasons, but I'd prefer if it wasn't the case TBH.
           | 
           | It was always a dirty hack.
        
       | lordnacho wrote:
       | Good list, and the litmus test is I would have disagreed with a
       | lot of it when I started, or at least I'd have wondered why it
       | mattered.
       | 
       | My summary, and it won't be useful at all, is that a lot of
       | programming decisions come down to judgement. Comment or not?
       | Config file or DSL? Is it ugly? Is is a rare feature of the
       | language? All of these things are the kind of thing that you
       | could argue if you wanted, but an experienced programmer will
       | likely have better arguments.
       | 
       | One thing I still don't agree with is the first one. There's a
       | lot of things, mostly trivial, that are easier to find on SO than
       | in the source code. In fact something like "what's the idiomatic
       | way to concat a string in $lang?" is best found on SO rather than
       | the source code, because the source code will allow more than one
       | way to do it.
       | 
       | For number 2 problems ("In many cases, what you're working on
       | doesn't have an answer on the internet."), the answer is again
       | judgement. For this you want to have a network of programmers
       | you've built up over the years that you can ask. I have a couple
       | of good friends on chat that I can just pop a question to, and it
       | saves a heck of a lot of time. Hard to find though, they have to
       | be someone who is basically gonna work for free for you, and you
       | have to provide a similar level of service when they have a
       | question for you.
        
       | yellowbanana wrote:
       | For me the most helpful general guideline has been. Make the code
       | easy to change.
       | 
       | I can break rules like DRY, if the repeating myself makes it easy
       | to change.
        
         | rckrd wrote:
         | Yep, modularity is immensely valuable. Requirements change.
         | Technology changes.
        
         | ithinkso wrote:
         | Yes, I often feel like 'refactorability' is way undervalued.
         | The focus is on writing abstractions that can be easily
         | extended to handle more cases but as soon as some case doesn't
         | fit, it will be hacked in because the code is abstracted in a
         | very narrow way and cannot be easily refactored to accommodate
         | this new case 'natively'.
         | 
         | Do that for a couple of years in a single codebase and the
         | beautiful abstraction design has changed into a state machine
         | with a transition between almost every pair of states
        
       | waynesonfire wrote:
       | Each point is true to me. Very nice job articulating these ideas.
        
       | SavantIdiot wrote:
       | There's a really good book called "Code Complete" from 1993
       | (revised several times) that I think captures a lot of this
       | sentiment in a more organized and illustrated way.
       | 
       | A lot of stuff on this list has been tribal knowledge for decades
       | (well, except for the part about build pipelines, language
       | choices, and Stack Overflow, etc.).
       | 
       | My first code mentors in the 80's & 90's said some of the same
       | things in this list, and I passed them down to my mentees (?) as
       | well.
       | 
       | https://www.powells.com/book/code-complete-9780735619678
        
       | giraffe333 wrote:
       | At least where I work, the DNS rule is "Batten's Law" because
       | that guy's said it so many times, and been right so many times.
       | 
       | https://www.battenworks.com/                 It's DNS       And,
       | when you're sure it's not DNS, it's DNS
        
       | naikus wrote:
       | > Syntactic sugar is usually bad.
       | 
       | When I read this, ES6 classes came to my mind :)
       | 
       | Great post btw!
        
       | temeritatis wrote:
       | > While rare, sometimes it's a problem with the compiler.
       | Otherwise, it's always DNS.
       | 
       | I don't quite understand this one? Does it refer to domain name
       | server? So if you're having network issues it's always DNS
       | problems?
       | 
       | > Corollary: Most code out there is terrible. Sometimes it's
       | easier to write a better version yourself.
       | 
       | I never cut-and-paste directly from stack overflow. I cut from
       | several sources, combine the best practices and adapt everything
       | to make something novel, and hopefully "better". But i think it's
       | important that you understand what it does before you use it.
       | This might seem self-evident, but my experience tells me not
       | everyone agrees with this methodology. If i find inspiration to a
       | solution, i usually leave a link to the original source or stack
       | overflow page.
        
         | vvoyer wrote:
         | The DNS part is a joke (I guess?) about how unreliable and
         | surprising DNS issues can be. You could do the same with
         | caching.
        
           | temeritatis wrote:
           | Oh certainly. In fact, caching issues (on multiple levels) is
           | a constant pain in the ass in my line for work anyway. It can
           | be so subtle sometimes that you spend hours looking at
           | something that shouldn't be an issue. But it is, and i think
           | we all know why.
        
         | [deleted]
        
       | bishoprook2 wrote:
       | After 30k/40k/??? hours of programming, I wish I had spent a
       | chunk of the time learning how to play the piano well or
       | something.
        
         | mastersummoner wrote:
         | Ouch. Well, never too late to take up piano or woodworking or
         | something. After 40k hours of programming, rock climbing might
         | be out though... your poor hands!
        
           | bishoprook2 wrote:
           | Luckily I managed to pop out of the other end of the machine
           | with my limbs intact.
        
         | GnarfGnarf wrote:
         | There's not as much money in piano as in programming.
        
           | bishoprook2 wrote:
           | Looking back, that shouldn't have been so much of a driving
           | force.
           | 
           | Now that I think of it, the right answer would have been
           | several 10k hour professions. I can't say that the products I
           | designed in 2020 were more complex or amazing than those in
           | 1980. It would have been a chance to achieve high levels of
           | proficiency in multiple fields.
        
       | gumby wrote:
       | Good list, and indeed not really advice for beginners.
       | 
       | I'm not sure reading the standard library for language X is
       | necessarily a good way to learn the conventions and practices of
       | a language. Typically a standard library contains a lot of
       | complex corner cases that don't need to be worried about when
       | writing ordinary code.
       | 
       | (Expanding). The standard library authors don't know the users of
       | the code. While when you're writing a piece of code with a
       | limited number of developers (could even be thousands) you might,
       | for example, say "all our accessors for class X return const
       | results" while the standard library authors have to handle the
       | non-const case"
        
         | pphysch wrote:
         | The advice is "learn from the best", not "learn from the
         | standard library". The Golang standard library just happens to
         | be among the best, according to the author.
        
         | rckrd wrote:
         | Good point. If you're writing your own library, maybe. If
         | you're writing business logic mostly, probably not. Thanks for
         | the perspective.
        
       ___________________________________________________________________
       (page generated 2021-08-06 23:00 UTC)