1. 16

There are plenty of shortcuts and pithy aphorisms already covered in books and everywhere online.

What are some that you discovered/formulated yourself? (Meaning: not read/told by someone else)

  1.  

  2. 25

    If you can’t find it, just start cleaning. If it’s a big purchase, sleep first. Musical instruments and exercise gear are always worth the money. Never run a credit card balance. Pants 2 days, shirts 1. Oil change every 3,000/6mos. Park far away. (Ok I copied some)

    1. 10

      3,000 miles is way too frequent if you’re running synthetic oil. Vehicles usually come with a manual that includes a maintenance schedule, follow that.

      1. 7

        At least for jeans, I wear them sometimes months straight without washing – unless I spill something on them.

        1. 1

          The environment is happier this way.

      2. 14

        Dumb code is often better than “The Right Way” code, even if there’s a modest amount of repetition.

        1. 10

          I don’t know if I found it myself or just sufficiently internalized it, but: always discard your prototypes. A prototype is more about the lessons than the result - it’s more work to try and massage a prototype into a production-quality program than it is to just start again with the knowledge you now have.

          Oh, and it doesn’t really work if you’re being paid, but: if you get stuck, give up. Dozens of times recently I’ve wracked my brain for an hour before shutting down and walking off and then figuring out the perfect solution. L’esprit de l’escalier, but in code, I guess.

          1. 6

            I agree about the second point but I prefer to call it “pausing” rather than “giving up.” It helps to have more than one thing to work on, so you can switch to your other project for a while to give your subconscious a little time to chew on the problem.

            1. 2

              I never understood that sentiment. I have thrown away quite a lot of code in my life, but every time it was because the prototype shown that the initial idea was fundamentally wrong. If the algorithms and program design are fundamentally correct, the code will still need extending and refactoring before it goes to production, but that’s a normal development process.

              If kind of issues in your prototypes warrant a rewrite from scratch?

              1. 2

                You’re right, “prototype” isn’t quite the right term. Maybe more like proof-of-concept, where the aim is to just show that it can be done without knowing from the start that it can, but I’ll still keep calling it a prototype for now.

                The main issue is usually that a decent chunk of the code is exploratory, written by someone (e.g. me two weeks prior) who has no idea of the problems that have yet to be solved. The end result is full of special-case conditions and corner-case bugs, and pretty much inextensible. At least, that’s my experience with my own projects and with prototypes I’ve been handed and told “here, I’ve done 80%, now you just finish the other [80%]”.

                Of course, if you do get everything right first try, great! But that’s probably because you thought you needed to write a prototype when you actually knew everything you needed to just start writing the first version. That’s why the kind of prototype I’m thinking of is more about the lessons - if you got everything right, you didn’t learn anything, and you didn’t make any mistakes you need to throw away, so you were just writing normal (production) code.

                There’s probably a skill there, though, in not overestimating yourself and assuming you’re not writing a prototype, and that’s why I’ll scrap any new code where I think “this works, but now I could do a better job in a fraction of the time”.

            2. 9

              My rule of thumb is “anything outside of git does not exist”. Thus, when working on a project:

              1. put all the code and small files inside a remote GIT repository
              2. put all (large) data files on a separate, read-only, easily accessible NAS
              3. every afternoon, delete my home dir

              this is a way of “dogfooding” the reproducibility of everything I do. Of course, it is difficult to be 100% strict about this, but as a rule of thumb it is nice.

              1. 2

                That’s the perfect way to test your backups actually

              2. 9
                • there will be unexamined complexity behind any proposal that starts with “why don’t you just …”

                • ten lines is a sensible limit for anything written as a shell script (based on my experience, yours may vary)

                • mocks are a code smell

                Not saying all of these are universally true, but they have all served me well as heuristics.

                1. 1

                  Do you have some good examples for how mocks are a code smell and example showing how to write effective code without them? I would like to write with less mocks.

                  1. 2

                    If I’m no allowed to show you the codebase I contribute to at $WORK (and I’m not) I think I’d have to go looking for them. My observation which leads to this rule of thumb is (1) that mocks are often (mis)used “to make the tests faster” - as standins for other objects which are outside the control/ownership of whoever wrote the mock, and (2) rarely is it that a mock is accompanied with a suitable contract test to ensure that the thing being mocked continues to behave in the way that the mock says it should behave.

                    If you’re not sinning in either of those ways then this rule of thumb does not apply to you and you’ll have to look to other sources of inspiration for reducing your use of them[*] - and without seeing how you are using them, I can’t really advise what that is. A quick example , suppose you have something like a Rails controller - it transforms the parameters it gets from Rack (e.g. parses them from strings into meaningful values), calls a domain or service object method, transforms the result back. Instead of writing a test that mocks the service object to check it receives the expected transformed values, you could extract the transformations and test them in isolation - then the controller itself is so trivial that (I would argue) there is small value in even writing a test for it.

                    [*] I mean, supposing you even need to. Statistically in my experience mocks are correlated with bad testing practices, but that doesn’t mean I think they are always misused.

                    1. 1

                      What about using Mocks to isolate your tests from the outside world (aka in place of db connections, filesystem or time calls)?

                2. 8

                  Comments that have typos or are otherwise sloppy seem more likely to have bugs near them, either nearby in the code or in the same commits.

                  Code pushed by people just before going on vacation should get extra scrutiny.

                  If you’re converting/compressing and transferring something, multiple layers of checksums can help figure out which layer is screwing it up. It’s easier to add them and then disable them once everything is working properly.

                  Sometimes starting from scratch and rewriting a prototype of something from memory is a good way to rethink the core design.

                  1. 2

                    Comments that have typos or are otherwise sloppy seem more likely to have bugs near them, either nearby in the code or in the same commits.

                    I agree with this in principle, except that there’s too much noise in this signal from people who are just bad at spelling and/or grammar. The real signal is when someone is being uncharacteriscally sloppy, which requires you to be familiar with that person’s language habits.

                    Code pushed by people just before going on vacation should get extra scrutiny.

                    Oh good grief yes, a thousand times. I’d go even further, and say that people should not be permitted to push code right before a vacation, at all.

                    1. 1

                      Yes, when somebody whose general writing voice you know is being uncharacteristically sloppy. That’s a great way of putting it.

                      I’m thinking of someone at a previous job who usually wrote well, but typos in comments often correlated with bugs – using the wrong constant for some calibration value, for example – and I realized it could have been a sign he was mentally exhausted but hadn’t realized it yet.

                    2. 1

                      Comments that have typos or are otherwise sloppy seem more likely to have bugs near them, either nearby in the code or in the same commits.

                      This is generally true, but not always. I have a colleague that everybody recognizes as a “superproductive programmer” who is unable to write a sentence without a few orthography or grammar errors. Even worse, he uses inconsistent formatting and spacing in his code, and he does not care. Yet, I have never seen anybody else able to write a continuous stream of useful and working code without bugs and very well-organized overall. Some people seem to just think at a higher level (and not at a lower level at the same time). This is not a matter of typing speed, he also types quite slowly.

                    3. 7
                      • Minimalism: If you haven’t used it in a year, get rid of it. If you can’t remember when you last used it, get rid of it.

                      • Tidying: Don’t ever leave a room without looking around for something that doesn’t belong in that room, and which you can carry with you to where ever it belongs.

                      • People: Just have the damn conversation.

                      1. 7

                        Mine is not profound at all and quite possibly wrong, but nonetheless: write in JavaScript, rewrite in Rust.

                        I’ve found out that every time I want to write X in Rust, I mess up somewhere along the way; writing in JS allows to prototype quickly and converge on design that I’d be able to rewrite in Rust (or throw it out entirely, saving borrowck time).

                        1. 1

                          If only JS had Rusty enums. I’m porting my old JS library to Rust right now, and I’ve realized that instead of temp objects with boolean flags, optional fields and extra methods, I can just model it neatly with a single enum.

                        2. 6

                          When you get stuck, simplify, either the code or the problem you are trying to solve. (this isn’t overly profound, but when taken seriously, it requires sometimes the courage to reduce your expectations)

                          1. 5
                            • Hope is for those who are too cowardly for reality.
                            • Stop worrying about the future, this civilization is done.
                            • Adding features to a programming language does not improve it.
                            • The people who “demand respect” are usually those unable to earn it.
                            • Trying “to be nice” unreservedly primarily benefits sociopaths and narcissists.
                            1. 3
                              • The user never describes the problem. They describe their failed attempt at solving it.
                              • Never start a sentence with “Logically, …”
                              • There is always a (snowflake) server that everyone fears its crash
                              • Once deployed it never gets updated (requires certain context)
                              • DNS, /etc/hosts, MTU and systemd are to “blame”
                              • When an outage happens, eat while you can. You do not know when you’ll get up.
                              1. 3

                                Any variable that holds a scalar value must have the units in the name. In other words, you should never have a variable named timeout. You always need to know the units, and you’re going to get it wrong if it’s not right in your face. Even if you think it’s obvious from the context, it won’t be. Naming it timeoutSeconds is going to save you hours of debugging.

                                (Possibly, this doesn’t apply to languages that can embed that information in the type system. Although even then I’m not sure…)

                                1. 3

                                  “Put it somewhere you can find it.”

                                  Digitally this means making it easy to search for. Physically this means putting similar things in similar places. Always.

                                  This is in contrast to how I used to keep important things as a kid: keep it secret! Who knows how many secrets I lost over the years…

                                  1. 2

                                    If code needs to be refactored or rewritten, it doesn’t mean it’s “bad”. More likely it was adequate code when it was written, but the context has changed: requirements grew, runway grew, project grew, other changes unblocked this one.

                                    1. 2

                                      I never, ever permanently delete code that I’ve put more than a couple of hours into. Usually there’s some nugget or some $thing that I did that I’ll remember in 2 years that I want to do again, or to reference how I structured $thing. I have 110 directories in my main projects directory and that will only ever continue to grow.

                                      1. 2

                                        If throwing out all your code and rewriting it seems daunting, then you haven’t fully understood the problem & you ought to throw out all your code and rewrite it again. (Some problems are not resolvable this way because they are specified in such a way that a clean solution is impossible – ex., adhering to web standards.)

                                        Write it as directly as possible, then (once you have discovered & fixed all the bugs) throw out your code and rewrite it so that, in addition to working, it is also good. If you try to write a perfect first draft, you will end up with code that is neither pretty nor functional.

                                        Bugs aren’t in the code, but in your head: your program is crashing perfectly correctly.

                                        Deadlines fundamentally change the incentive structure around learning, making undirected deep study impossible and encouraging to you learn what everybody else already knows, so it’s really important to learn as much as you can before you’re on the clock.

                                        Time pressure is the only thing that can justify most dependencies, since they inevitably become a maintenance headache. If you’re spending more than a few hours finding a dependency that fits your needs or learning how to use it, you are probably better off writing it yourself. (Even if you don’t then use your own version, you will at least now be better equipped to understand, vet, and predict the behavior of third-party implementations.)

                                        It is important to make the behavior of code obvious; otherwise, someone (maybe yourself in six months) will misunderstand perfectly functional code as buggy and misunderstand buggy code as perfectly functional.

                                        The most valuable thing you know is always going to be the thing everybody else avoided learning on the grounds that it would never become useful (until it unexpectedly became useful). If you optimize too close to your own expectations, you will be imprisoned by them, unable to see much better alternatives just outside the norm.

                                        1. 1

                                          No matter how many lighters you buy, you’re never more than one away from completely unable to find a lighter.

                                          1. 1
                                            • Legacy systems are clustered.
                                              Some users or departments will have most of the legacy systems.
                                            • People and processes are more adaptable than software.
                                              It can be substantially easier to change a workflow or process than a software system.
                                            • 3 months is the default estimation time.
                                              If someone gives 3 months as a time estimate they probably don’t understand the problem.
                                            1. 1

                                              I noted quite a lot of rules for myself. Some are more specific, others more abstract. I refined the list over the years.

                                              https://wiki.nikitavoloboev.xyz/focusing/rules

                                              1. 1

                                                I gave a quick look at your wiki, it made me consider having a wiki for myself too. I really liked the idea, I don’t know if I would have the courage to put it online though, I’ll probably censure myself if I do.

                                                For how long have you maintained the wiki? Where did you get the idea?

                                                1. 2

                                                  Got the idea from this wiki: https://github.com/yoshuawuyts/knowledge

                                                  Setup the wiki in 2017. Been updating it daily ever since.

                                                  Updating tools to access it too.

                                              2. 1

                                                if I’m even slightly unsure - ask somebody.

                                                1. 1

                                                  If you aren’t absolutely sure how the code will be used, don’t write anything until you have had the requestor explain it to your satisfaction. Otherwise you will code the wrong thing.

                                                  The prototype is not done until tests are written for it as well.

                                                  Integration tests are good for ensuring the design works. Unit tests are good for tracking down where it doesn’t.

                                                  Understand investing and pay yourself first. Having the financial freedom to say no to bad jobs/ideas/unethical requests is core to being a ethical engineer.

                                                  You brain is part of your body, so take care of it. Eat healthy, find some way to be active that doesn’t feel like a chore. Do not expect to have good health in retirement if you spend your working years spending 8 hours in a chair staring at a monitor without any countermeasures.

                                                  “Everything in moderation, including moderation.” - Lost Horizons by James Hilton

                                                  1. 1

                                                    You can always start at main() and stop when your expectations are no longer satisfied.

                                                    You shouldn’t always do that.

                                                    1. 1

                                                      If a program was working, and now it doesn’t, then something changed. If it wasn’t the program (and at $work, it’s almost never been the program I wrote, and changing the program in production is a production in itself [1]) then it’s something about the environment or network that has changed.

                                                      This goes in line with my view of debugging—once you have eliminated the impossible, whatever remains, however improbable, is the answer. Also, the scientific method applied to debugging works wonders.

                                                      [1] SLAs with the Monopolistic Phone Company. Doing a deployment is Kabuki Theater at its finest.