1. 2

    Remove all externalities on your metrics, and break it down to things you can completely control.

    How many challenging books did you read last year? Blogs are fine, but rarely get deeper than chapter two of a book. If you’re a Python programmer, and you rarely touch the database, get a great book on SQL and dive deep. Don’t just skim the tenth C# book in a row. Be uncomfortable, push your boundaries with each book. Minimum read one a year. I recommend books with exercises to complete, and do them all. Here are my favorites I recommend: http://deliberate-software.com/page/books/

    Make a daily practice routine, maybe 20 minutes every day on the train. Sit and actually write software. Start with small tightly constrained problems, then build out something big.

    Peter Norvig has some great examples on how to improve: http://norvig.com/21-days.html

    1. 3

      What I want is a 90s Microsoft intelliwhatever split keyboard with the traditional arrows layout, but mechanical switches. And a detachable cable, so I can simply unplug it on my desk without having to trace the cable back to my USB hub / computer when I want to clean it.

      1. 3

        I love the Natural 4000, but the switches in it are garbage!

        Nothing else solved my wrist problems. Not ice, not heavy weight lifting, not stretches, not regularly scheduled breaks, and not a $400 Ergodox. Heck even full time pair programming only keeps it mildly at bay. But the Natural, no pain, even if I’m typing full speed all day. Not bad for a $25 keyboard.

        1. 2

          Yeah it looks close to what I want, but I just can’t give up the satisfying feel and sound of nice clacky mechanical keys.

      1. 7

        These are nice, but to be fair, I think when most people want this level of management, they start using Jira or likewise.

        1. 1

          Yes, JIRA does do all of the things mentioned in this article if you count in the various plugins like Agile and Tempo (time tracking)…I think the only thing it can’t do are “confidential issues”, you’d have to make the whole project private IIRC.

          That said, the tools that JIRA delegates to like Stash and Bamboo leave a lot to be desired. We’re sorta tearing our hair out with Bamboo’s inability to have reconfigure builds (like with a .bamboo.yml file) on a per-branch basis.

        1. 1

          I began programming in 90s, when OO hype was at it’s highest, and so I definitely feel the apparent failure of reuse strongly even now.

          Of course, one part of reuse is the “glass half-empty/glass half-full” effect. Of course code reuse happens but of course the failure of reuse also happens. The key problem is describing the ways that this failure happens, I think.

          I’d divide our apparent failures into two parts.

          A. The failure of “effortless” reuse. OO originally talked about objects being created during the ordinary process of coding, as if the problems of engineering libraries could be ignored. This fantasy thankfully is mostly done. However, this is also the less fundamental part of the failure of the idea of reuse, since there’s a solution - just make or use object-libraries or just libraries (whether OO, DSL or procedural approaches work better here is a secondary question imo).

          B. The less-than-complete-success of any encapsulation effort. The failure of OO, procedural or other library in terms of the failure of these to fully hide their implementation details when they used frequently in a large-ish application. This isn’t saying libraries, operating systems, graphic drivers and high level language are useless. The problem is all the abstractions wind-up “leaky” on some level and so when the programmer is programming and using, say, 10 abstraction layers, the programmer is going to be forced to consider all ten layers at one point or another (though naturally some will be worse than others, some only in terms of performance but that’s still consideration imo). The lpad event that broke the web a bit ago is one extreme example of this sort of problem.

          So “B” is bigger problem. It seems to limit how many layers of abstraction can be stacked together. I don’t know of any studies that directly tackle the question on these terms and I would be interested if anyone has links here.

          1. 1

            I sometimes think we are sometimes just really bad at memorizing advice and passing it on accurately. While OOP was advocated for with the “reuse” argument, there was also a “use before reuse” principle. But these subtleties just seem to get lost, when people start writing up syllabuses and introductory material.

            I learned programming mostly with tutorials and books that were written in the 90ies when OOP craze was in full bloom (and that material spent a lot of time explaining “OOP principles”, much more I think than a modern book on Java/C++/Python does). Anyway, I often did not find OOP helpful a lot for structuring my code, finding good OO models was hard and hardly seemed worth it.

            Fast forward this month. I borrowed a book on DDD patterns and started tinkering with the patterns outlined there and I must say for the first time in my life I have the feeling that I have a reasonable strategy in front of me for mapping business logic to classes/objects. And differs a lot from the naïve examples that I just recently saw in a mandatory corporate training.

            Who knows when functional programming will reach this point where the original motivations are already buried so deep that they cannot be seen anymore.

            1. 3

              Having invested a lot of time into DDD over the last eight years, I personally think a lot of it isn’t as valuable as it initially seems. The various materials ultimately describe new names for things you probably already have names for, but this author wants you to call something else.

              While neat to read, I’d caution against trying to go through your codebases renaming everything, which anecdotally has been what new readers first do. That often is a big time sink that doesn’t have any payoff at all other than just new names for old concepts.

              However, reading about CQRS (an often referenced outgrowth of DDD) is a big deal, and would cause you to actually structure everything in a different way that can add potential benefit (immutability, fast read operations, etc). I highly recommend at least reading up on that.

          1. 2

            About half of these are wrong, in my experience, but the entertaining and edifying exercise lies in figuring out which half.

            1. 2

              I’d be curious to hear which you find wrong. Most to me seem actually very similar to what I’ve seen in working in a big project owned by a small team.

            1. 2

              I liked this list a lot.

              Even though I’m a rabid language fanatic, I disagree that the listed functional languages are the only serious options to build scalable software.

              The rest makes a lot of sense in my mind.

              1. 14

                At my day job we primarily use Python for our server side stack. I like the language, but I still feel like I don’t really know what I’m doing with it. I have 15 years of PHP under my belt, so I often know what I want to do, but not how to make it happen in Python. I don’t feel like I really grok the module system. I definitely don’t understand the class system. What the hell is a generator and how does it work the way it does? I am so lost.

                Frankly, my reaction to reading this is that the author has some important gaps in their understanding of programming. Python is not a particularly difficult programming language - in fact, precisely because it is straightforward to understand, it’s deliberately taught to 1) beginner students of programming and 2) statisticians, scientists, and other people who need to do some computation in the course of their work but who are not primarily programmers. Python classes are the same sorts of object-oriented classes that have been mainstream for 30+ years, nothing about generators should be particularly difficult to someone who understands what a for-loop does. And modules? Are modules (in either Python or Javascript) really something that’s hard to grok? It really throws me for a loop to see someone with 15 years of experience across at least two programming languages complaining about feeling lost in this way. Is PHP really that bad?

                I understand that part of the point of this essay is the complaint that the author doesn’t want to spend as much time immersing themselves in new technologies as they used to because of their family obligations (which is understandable), but also doesn’t want to be left behind in terms of their skillset. But the specific things he’s complaining about not understanding well - and not being motivated to spend the time on understanding - strike me as fairly basic and general features of programming languages, that I think would be reasonable for an experienced developer to understand

                1. 12

                  There’s those with 15 years of experience and those with 1 years experience 15 times. Not implying the author is in the latter. But I’ve worked with many over my career that refused to do anything outside their comfort zone and as a consequence didn’t learn anything new for years.

                  1. 2

                    I’d say that even 15 times 1 year experience is SO much better than how this guy is presenting himself. You are bound to learn something new by learning a new language.

                    This sounds more like 1 year experience and 14 of just being there.

                  2. 2

                    To me the burning question that came out of this post was “how do you decide what to learn next”?

                    1. 1

                      I made a list of books that really helped expand my abilities:

                      http://deliberate-software.com/page/books/

                  1. 7

                    Single-page apps are much more expensive to build than multi-page apps. In most cases, there is no business reason to choose this architecture. The problems it’s trying to solve can be address in simpler ways without excessive costs and complexity. There are cases where an SPA makes sense but this is a topic for another article.

                    Looking forward to the counter-article. I believe the cases where a SPA makes sense are capability driven, whereas this article is very solid advice when primarily cost driven.

                    1. 7

                      I have built multiple large SPAs, used jquery/backbone/angular/react in anger, and have maintained codebases for enough time to feel the pain from my earlier decisions.

                      I have never seen a project where an SPA turned out to be the right answer in retrospect.

                      It’s proven more complex and time consuming than building progressive enhancement and fast server responses, every time.

                      1. 6

                        I have never seen a project where an SPA turned out to be the right answer in retrospect.

                        This might be true, but surely there are applications which succeeded because, and not despite of, being more SPA-like and less hypertext-like. Gmail being a SPA is a competitive advantage.

                        It’s nice to see the fashion-pendulum swing the other way on SPA’s, since they are definitely overused.

                        I want to hear more about when a SPA is the right choice, knowing that the answer isn’t never.

                        1. 3

                          Gmail is an interesting example - despite putting in a ton of engineering, FastMail (also an SPA) have a much, much faster UI with a smaller team.

                          “SPA” is a spectrum, (eg) react-router apps clearly fits the bill, but (for instance) turbolinks apps are technically also a single page. Drawing a more granular distinction (eg: virtualdom vs innerHTML, pushstate vs pageload, json vs html on the wire) can be more valuable.

                          1. 2

                            Previous comments touched on it: SPAs make sense when cost isn’t as important as capabilities. Google can afford to spend hundreds of millions on Gmail, in that case capabilities are more important than cost.

                            Expensive architectures are fashionable because they signal to others that the work you are doing is so important your team can afford any cost to squeeze out that last feature.

                            I’ve written about this before, and I think it still stands: http://deliberate-software.com/pop-culture-architecture/

                            1. 2

                              It’s not only about capabilities. If the choice you’re facing is:

                              1. Spend $1M building an SPA and earn $250k in profit.
                              2. Spend $500k building an MPA and earn $250k in profit.

                              then the decision isn’t really that difficult ;-) I can’t speak for Google but I think it’s reasonable to assume that their decisions are made on business considerations and architectural choices provide material contribution to the bottom line.

                        2. 3

                          I believe the cases where a SPA makes sense are capability driven, whereas this article is very solid advice when primarily cost driven.

                          It’s probably also experience-driven. If you’re comfortable creating SPAs then I don’t think there’s a good argument here to stop doing that. You might even find that it slows down development a lot - say if you have to switch to server-side rendering (which I think is what “MPA” means) in a language / templating system you’re not familiar with. I’m fairly comfortable with both Jinja and React, and there’s no way I’d want to go back to Jinja after React. I guess I could render my React server-side, but at that point you’re pretty close to just using something like Gatsby or Next.js and getting the best of both worlds.

                          1. 1

                            I’ll definitely post it here when it’s done. So far, I left some ideas in a comment here.

                            My assumption is we need to take revenues and costs into account and then pick the solution with the best return on investment. It’s a bit difficult to measure value of UX to users and the corresponding increase in profit and it’s doable. That’s one part of the equation. Then we need to asses what it takes to deliver that UX and this is the part covered in the article. For some projects the answer will be an MPA for others an SPA and there are also shades of grey in between.

                          1. 1

                            I disagree that you should take the average and add 20% for an estimate.

                            Recently, I’ve been working on a huge banking system that has shipped new releases filled with features every quarter for the last 15 years. We are known for having exceptionally high quality software. What does work is to have the group come to consensus on an estimate, record that as an “ideal unit”, then do a couple weeks of work and see how many “ideal units” get completed each week. Ideally all estimates are small enough to complete in under a week. Take that number and use that to find your multiplier for the release. Also known as “yesterday’s weather.” Recheck every three weeks or so with an average of the last three weeks.

                            Even the best teams I’ve seen be off by as much as 10x when starting a new type of project, and 4-5x on regular work when there are new people on the team, etc.

                            I think this is a massive reason why we are usually pretty accurate about estimates. It’s flexible, simple, takes into account people coming and going, etc. I cannot recommend this enough.

                            We originally learned it from here: https://www.jamesshore.com/Agile-Book/estimating.html

                            1. 13

                              You might find this interesting, it’s an attempt to predict bugs by language features. Unsuccessful, but still interesting enough for me to finish.

                              http://deliberate-software.com/safety-rank-part-2/

                              1. 5

                                edit: Hey that is actually really cool and interesting, (the point about clojure is interesting too). It is also a pretty smart way to gather data in a situation where it is normally extremely hard to do so.

                                Something I just read today too - less about bugs, but more about robustness

                                http://joeduffyblog.com/2016/02/07/the-error-model/

                                1. 3

                                  Thanks! Good link too.

                                  Speaking of which, I highly recommend learning Haskell. It’s a lot of work, but it’s really changed how I think about programing. I would absolutely go back and do it again. It really makes the easy things hard (tiny scripts) but the hard things easy. Very much worth learning in my mind.

                                2. 1

                                  While Tail Call Optimization would certainly be nice to have in Go to improve performance, in practice it’s not a cause of defects because people just use iteration instead of recursion to accomplish the same thing. It doesn’t look as “nice” but you don’t get stack overflows.

                                  1. 1

                                    Arguably that could be said of all the things on that list. Every programming language community has idioms to best use the available feature set.

                                    Specifically for recursion, I was assuming that the mental shuffle to convert something from recursion (often more elegant and simple) to iteration would cause issues. Since the whole model doesn’t work very well, I clearly was wrong in multiple places, and this very well could be one.

                                    1. 5

                                      Specifically for recursion, I was assuming that the mental shuffle to convert something from recursion (often more elegant and simple) to iteration would cause issues.

                                      I could be wrong, but I suspect most developers find iterative algorithms more straightforward to write iteratively, not recursively, and consider writing them recursively a mental shuffle.

                                      It wouldn’t surprise me if comfort with recursive algorithms is a predictor of developer proficiency, though.

                                      1. 2

                                        You are probably right, but I’d guess now that is more because most developers work in languages that don’t support recursion. Originally, I was also going for the idea that it offers a way for the developer to make a mistake without realizing it. In this case, they don’t realize that recursion isn’t tail optimized, since the language allows it without warning. But since I have yet to see anyone use recursion unless they are used to languages with immutability (and even then they probably just use fold), it probably doesn’t come up much.

                                        As such, it probably makes sense to remove that item, which doesn’t change much, just slightly raises the “c-style” languages and lowers the “lisp-style”.

                                        1. 2

                                          but I’d guess now that is more because most developers work in languages that don’t support recursion.

                                          Most people think about problem solving in an iterative way. They’ll do this, then this, maybe this conditionally, and so on. Imperative. Iterative. Few people think of their problems in a recursive way without being taught to do so. That’s probably why most prefer iterative algorithms in programming languages.

                                          1. 3

                                            To fully shave the yak, I’d argue this is entirely a product of how programmers are taught. Human thinking doesn’t map perfectly to either format. Recursion is just saying, “now do it again but with these new values”, and iteration requires mutations and “storing state”. Neither are intuitive - both need to be learned. No one starts off thinking in loops mutating state.

                                            Considering most programmers learn in languages without safe recursion, most programmers have written way more iterative loops so are the most skilled with them. That’s all, and this isn’t a bad thing.

                                            1. 3

                                              They might not either be very intuitive. Yet, educational experience shows most students pick up iteration quickly but have a hard time with recursion. That’s people who are learning to program for the first time. That indicates imperative, iterative style is closer to people’s normal way of thinking or just more intuitive on average.

                                              Glad we had this tangent, though, because I found an experimental study that took the analysis further than usual. I’ll submit it Saturday.

                                              1. 1
                                              2. 2

                                                I agree. And I think there’s a lot that just isn’t possible with that mindset.

                                          2. 3

                                            Specifically for recursion, I was assuming that the mental shuffle to convert something from recursion (often more elegant and simple) to iteration would cause issues.

                                            I think it really depends on the algorithm. To my understanding, mapping and filtering is a lot easier recursively, but reducing and invariants tend to be easier iteratively.

                                          3. 1

                                            I think I remember reading Russ Cox doesn’t like tail recursion because you lose the debug information in the stack traces.

                                            1. 2

                                              This is a big pet peeve of mine: because many languages use pointers in stack traces, you can’t see what the values were at that time. I think storing the value instead of just the pointers would be expensive, but it sure would be useful.

                                              1. 1

                                                What information would you lose?

                                                1. 2

                                                  I think that in this example, you’d think that initial directly called final:

                                                  def initial():
                                                      intermediate()
                                                  
                                                  def intermediate():
                                                      final_caller:
                                                  
                                                  def final():
                                                      throw "boom"
                                                  

                                                  This could make it extremely hard to debug if intermediate happened to modify state and it was the reason why final was failing.

                                                  1. 1

                                                    I think the call stack may be convenient for this purpose, but not necessary. I’m sure there are other (potentially better & more flexible) ways to trace program execution.

                                          1. 9

                                            totally happy with a Microsoft ergonomic keyboard.

                                            1. 4

                                              Same here.

                                              I’d love to have a fancy mechanical keyboard with lots of option keys etc. but I don’t have endless spare time to research let alone configure something like that.

                                              1. 2

                                                Same on both counts

                                              2. 1

                                                The MS Natural 4000 is perfect for me: I went from pain after an hour to no pain no matter how much I type. It’s only $30! Great stuff.

                                                I’ve got an ergodox, but getting used to the thumb keys at work but not having it on my laptop at home was just too much to get used to.

                                              1. 1

                                                I suspect some form of glove+VR interfaces might surface in the same way violins still exist in a world where guitars exist. It’s easier to learn guitar, but there’s things you just can’t do with it, so some people still learn violin.

                                                But then again, no one learns the Engleberts Violin, instead they continue to learn a qwerty keyboard simply because of social velocity. Only a few learn something like devorak, and almost no one learns a chording keyboard.

                                                Heck, most business email I get seems to come from phones, and most I send is on a phone. We’ve already started to move towards degraded interaction in business contexts, simply because it’s so convenient.

                                                1. 16

                                                  As a junior developer doing my best to learn as much as I can, both technically and in terms of engineering maturity, I’d love to hear what some of the veterans here have found useful in their own careers for getting the most out of their jobs, projects, and time.

                                                  Anything from specific techniques as in this post to general mindset and approach would be most welcome.

                                                  1. 34

                                                    Several essentials have made a disproportionate benefit on my career. In no order:

                                                    • find a job with lots of flexibility and challenging work
                                                    • find a job where your coworkers continuously improve themselves as much (or more) than you
                                                    • start writing a monthly blog of things you learn and have strong opinions on
                                                    • learn to be political (it’ll help you stay with good challenging work). Being political isn’t slimy, it is wise. Be confident in this.
                                                    • read programming books/blogs and develop a strong philosophy
                                                    • start a habit of programming to learn for 15 minutes a day, every day
                                                    • come to terms with the fact that you will see a diminishing return on new programing skills, and an increasing return on “doing the correct/fastest thing” skills. (e.g. knowing what to work on, knowing what corners to cut, knowing how to communicate with business people so you only solve their problems and not just chase their imagined solutions, etc). Lean into this, and practice this skill as often as you can.

                                                    These have had an immense effect on my abilities. They’ve helped me navigate away from burnout and cultivated a strong intrinsic motivation that has lasted over ten years.

                                                    1. 5

                                                      Thank you for these suggestions!

                                                      Would you mind expanding on the ‘be political’ point? Do you mean to be involved in the ‘organizational politics’ where you work? Or in terms of advocating for your own advancement, ensuring that you properly get credit for what you work on, etc?

                                                      1. 13

                                                        Being political is all about everything that happens outside the editor. Working with people, “managing up”, figuring out the “real requirements’, those are all political.

                                                        Being political is always ensuring you do one-on-ones, because employees who do them are more likely to get higher raises. It’s understanding that marketing is often reality, and you are your only marketing department.

                                                        This doesn’t mean put anyone else down, but be your best you, and make sure decision makers know it.

                                                        1. 12

                                                          Basically, politics means having visibility in the company and making sure you’re managing your reputation and image.

                                                          A few more random bits:

                                                      2. 1

                                                        start a habit of programming to learn for 15 minutes a day, every day

                                                        Can you give an example? So many days I sit down after work or before in front of my computer. I want to do something, but my mind is like, “What should I program right now?”

                                                        As you can probably guess nothing gets programmed. Sigh. I’m hopeless.

                                                        1. 1

                                                          Having a plan before you sit down is crucial. If you sit and putter, you’ll not actually improve, you’ll do what’s easy.

                                                          I love courses and books. I also love picking a topic to research and writing about it.

                                                          Some of my favorite courses:

                                                          1. 2

                                                            I’ve actually started SICP and even bought the hard copy a couple weeks ago. I’ve read the first chapter and started the problems. I’m on 1.11 at the moment. I also started the Stanford 193P course as something a bit easier and “fun” to keep variety.

                                                      3. 14

                                                        One thing that I’ve applied in my career is that saying, “never be the smartest person in the room.” When things get too easy/routine, I try to switch roles. I’ve been lucky enough to work at a small company that grew very big, so I had the opportunity to work on a variety of things; backend services, desktop clients, mobile clients, embedded libraries. I was very scared every time I asked, because I felt like I was in over my head. I guess change is always a bit scary. But every time, it put some fun back into my job, and I learned a lot from working with people with entirely different skill sets and expertise.

                                                        1. 11

                                                          I don’t have much experience either but to me the best choice that I felt in the last year was stop worrying about how good a programmer I was and focus on how to enjoy life.

                                                          We have one life don’t let anxieties come into play, even if you intellectually think working more should help you.

                                                          1. 9

                                                            This isn’t exactly what you’re asking for, but, something to consider. Someone who knows how to code reasonably well and something else are more valuable than someone who just codes. You become less interchangeable, and therefore less replaceable. There’s tons of work that people who purely code don’t want to do, but find very valuable. For me, that’s documentation. I got my current job because people love having docs, but hate writing docs. I’ve never found myself without multiple options every time I’ve ever looked for work. I know someone else who did this, but it was “be fluent In Japanese.” Japanese companies love people who are bilingual with English. It made his resume stand out.

                                                            1. 1

                                                              . I got my current job because people love having docs, but hate writing docs.

                                                              Your greatest skill in my eyes is how you interact with people online as a community lead. You have a great style for it. Docs are certainly important, too. I’d have guessed they hired you for the first set of skills rather than docs, though. So, that’s a surprise for me. Did you use one to pivot into the other or what?

                                                              1. 7

                                                                Thanks. It’s been a long road; I used to be a pretty major asshole to be honest.

                                                                My job description is 100% docs. The community stuff is just a thing I do. It’s not a part of my deliverables at all. I’ve just been commenting on the internet for a very long time; I had a five digit slashdot ID, etc etc. Writing comments on tech-oriented forums is just a part of who I am at this point.

                                                                1. 2

                                                                  Wow. Double unexpected. Thanks for the details. :)

                                                            2. 7

                                                              Four things:

                                                              1. People will remember you for your big projects (whether successful or not) as well as tiny projects that scratch an itch. Make room for the tiny fixes that are bothering everyone; the resulting lift in mood will energize the whole team. I once had a very senior engineer tell me my entire business trip to Paris was worth it because I made a one-line git fix to a CI system that was bothering the team out there. A cron job I wrote in an afternoon at an internship ended up dwarfing my ‘real’ project in terms of usefulness to the company and won me extra contract work after the internship ended.

                                                              2. Pay attention to the people who are effective at ‘leaving their work at work.’ The people best able to handle the persistent, creeping stress of knowledge work are the ones who transform as soon as the workday is done. It’s helpful to see this in person, especially seeing a deeply frustrated person stand up and cheerfully go “okay! That’ll have to wait for tomorrow.” Trust that your subconscious will take care of any lingering hard problems, and learn to be okay leaving a work in progress to enjoy yourself.

                                                              3. Having a variety of backgrounds is extremely useful for an engineering team. I studied electrical engineering in college and the resulting knowledge of probability and signal processing helped me in environments where the rest of the team had a more traditional CS background. This applies to backgrounds in fields outside engineering as well: art, history, literature, etc will give you different perspectives and abilities that you can use to your advantage. I once saw a presentation about using art critique principles to guide your code reviews. Inspiration can come from anywhere; the more viewpoints you have in your toolbelt the better.

                                                              4. Learn about the concept of the ‘asshole filter’ (safe for work). In a nutshell, if you give people who violate your boundaries special treatment (e.g. a coworker who texts you on your vacation to fix a noncritical problem gets their problem fixed) then you are training people to violate your boundaries. You need to make sure that people who do things ‘the right way’ (in this case, waiting for when you get back or finding someone else to fix it) get priority, so that over time people you train people to respect you and your boundaries.

                                                              1. 3

                                                                I once saw a presentation about using art critique principles to guide your code reviews. Inspiration can come from anywhere; the more viewpoints you have in your toolbelt the better.

                                                                The methodology from that talk is here: http://codecrit.com/methodology.html

                                                                I would change “If the code doesn’t work, we shouldn’t be reviewing it”. There is a place for code review of not-done work, of the form “this is the direction I’m starting to go in…what do you think”. This can save a lot of wasted effort.

                                                              2. 3

                                                                The biggest mistake I see junior (and senior) developers make is key mashing. Slow down, understand a problem, untangle the dependent systems, and don’t just guess at what the problem is. Read the code, understand it. Read the code of the underlying systems that you’re interacting with, and understand it. Only then, make an attempt at fixing the bug.

                                                                Stabs in the dark are easy. They may even work around problems. But clean, correct, and easy to understand fixes require understanding.

                                                                1. 3

                                                                  Another thing that helps is the willingness to dig into something you’re obsessed with even if it is deemed not super important by everyone around you. eg. if you find a library / language / project you find fun and seem to get obsessed with, that’s great, keep going at it and don’t let the existential “should i be here” or other “is everyone around me doing this too / recommending this” questions slow you down. You’ll probably get on some interesting adventures.

                                                                  1. 3

                                                                    Never pass up a chance to be social with your team/other coworkers. Those relationships you build can benefit you as much as your work output.

                                                                    (This doesn’t mean you compromise your values in any way, of course. But the social element is vitally important!)

                                                                  1. 4

                                                                    I was interested in what he was saying just up until he said

                                                                    Some may even be lucky enough to find themselves doing Extreme Programming, also known as ‘The Scrum That Actually Works’.

                                                                    My experience with XP was that it was extremely heavyweight and did not work well at all. It created the greatest developer dissatisfaction of any of the versions of Agile I’ve encountered.

                                                                    1. 5

                                                                      Couldn’t disagree more – the most successful team I was on was heavily into XP. When people say it’s heavyweight, they’re usually talking about pair programming. I’m not sure what people have against it; I’ve found it’s a great way to train junior developers, awesome for tricky problems, and generally a great way to avoid the problem of, “Oh this PR looks fine but redo it because you misunderstood the requirements.”

                                                                        1. 2

                                                                          I don’t want to discount your experience, but it sounds like the issues you’ve had with pair programming are more with the odd choices your employer imposed.

                                                                          Both people have specialized editor configs? Sure, switch off computers or whatever too; no need to work in an unfamiliar environment.

                                                                          And if one person is significantly less experienced than the other, that person should be at the keyboard more often than not – watching the master at work will largely be useless.

                                                                      1. 3

                                                                        Why I like XP over anything else is the focus on development practices rather than business practices. Pairing, TDD, CI, <10 minute builds, WIP, whole team estimation, etc are all used to produce a better product, faster.

                                                                        The weekly retrospective offers a way to adjust practices that aren’t working and bolster those that are.

                                                                        1. 2

                                                                          Agreed 100%. It turned my head a bit when he thought Agile was too prescriptive, but then was considering an even more prescriptive methodology.

                                                                          1. 1

                                                                            What was your experience with XP? Also, scrum is heavyweight as well in my experience and doesn’t work excellently in an actually agile environment like a startup. Feels like it could work in corp. though.

                                                                          1. 2

                                                                            Very interesting, because in the average language, some can be expressed as run time checks, others as compile time checks. Getting into more dependently typed languages allows more to be expressed at compile time, but still some are quite tricky.

                                                                            Reminds me of the Tony Morris Tic Tac Toe game, which was surprisingly challenging, and gave me a great afternoon of fun. http://blog.tmorris.net/posts/understanding-practical-api-design-static-typing-and-functional-programming/

                                                                            1. 8

                                                                              After finishing SICP I enjoyed Programming Languages which was about building interpreters in Racket. You’ll want to follow along with the book and the course assignments, for some reason they keep them separate. http://cs.brown.edu/~sk/Publications/Books/ProgLangs http://cs.brown.edu/courses/cs173/2016/assignments.html

                                                                              I really enjoyed Haskell Programming From First Principles, which is about learning Haskell. Since we’re programmers, we can learn to wield both sides of the Force, Lisp AND Haskell. http://haskellbook.com

                                                                              Likewise, Let Over Lambda is excellent and I’d argue even more mind bending than SICP and is about DSLs in CL macros, with a final project of making the language Forth a valid DSL in CL: https://letoverlambda.com/index.cl/toc

                                                                              I’m only part way through, but I really like Software Foundations. It’s about dependently typed proofs in Coq. Really good stuff. Suddenly you realize there’s not just two sides to the Force. https://softwarefoundations.cis.upenn.edu/current/index.html

                                                                              All of these were very similar to SICP in difficulty, exercise length, and value to my ability to write and comprehend software. I can’t recommend them enough.

                                                                              1. 3

                                                                                Brown further developed the course - CSCI 1730 based on a revised version of PLAI (and an early version of typed racket) with video lectures and assignments.

                                                                                PLAI’s spiritual successor Programming and Programming Languages is also available based on a new language called Pyret.

                                                                                1. 2

                                                                                  Oh cool! I was taking the course when they switched mid-semester to typed racket (which was a big improvement), its nice to see they’ve continued revising further.

                                                                              1. 10

                                                                                I have yet to hear anyone say that they enjoy pair programming all day, every day, forever.

                                                                                I love pair programming — a key part of my interviews includes a pairing session — but I quite frankly can’t pair for more than about an hour at a time, tops about four sessions per day with at least two different people. That’s my personal preference.

                                                                                I would be interested to know if the authors team consistently concludes during regularly scheduled retrospective sessions that everyone enjoys doing forced pairing enough to keep it a thing.

                                                                                1. 6

                                                                                  Let me be the first. :) I love pair programming, and miss it whenever I have to code without it. Doing it for a year kind of ruined me for working alone. (And I’m not an extrovert! In general, I shy away from being around people.)

                                                                                  I read about bad pair programming experiences and count myself as lucky that all the partners I had were really great people and invested in the process. I can see how it could go sideways.

                                                                                  1. 7

                                                                                    In the past, I’ve misunderstood what “pair programming” actually means. Could you elaborate and say more exactly about what it means to you? What does your daily process look like? How did you deal with the practical problems stated, like, say, different editor configs or such?

                                                                                    1. 2

                                                                                      I’m not the OP, but here is a write-up of my good experience pairing.

                                                                                      http://deliberate-software.com/pairprogramming/

                                                                                      1. 2

                                                                                        OP here: I remember reading your article a while ago (it’s really good!). When I saw the below quote I realized you were talking about me.

                                                                                        Some developers love the idea of pairing, not the practice of pairing; they often leave when they discover that distinction

                                                                                        A lot of days I would wish I could like it, so I could enjoy my job. I felt like I gave it a fair shot too (2 years).

                                                                                        1. 2

                                                                                          Do you all have a notion of “going odd”? I probably am “odd” at least 3 sessions a week, which helps for time to think and recharge.

                                                                                          1. 1

                                                                                            We did but if you’re on a team with an even headcount you’ll never go odd. I wish we could’ve gone odd more often.

                                                                                            1. 1

                                                                                              Hmm that’s unfortunate.

                                                                                              Even with 6-10 in our office, one pair splits most of the time to handle odd work, research, or support.

                                                                                              Recognizing when to split pairs while still maintaining the tenet of “all production code written by a pair” goes a long way.

                                                                                      2. 2

                                                                                        Sure – when I did it full time, I had the same partner for about a week at a time before switching. We worked on a project for 8 hours a day, coding for about 45 minutes at a time with 10-15 minute breaks in between. We usually were co-located, although not always. We had two keyboards and mice, and usually two monitors, and would switch off who was writing code differently depending on the partner dynamic, but it was usually pretty organic – whenever your partner was stuck on what to write and you had an idea, you’d take over.

                                                                                        Different editor configurations were definitely a thing that could cause friction, but I don’t see that as a bad thing. I both learned a lot about editor tricks and gained an appreciation for keeping your config as simple as possible. We mainly worked in console-based editors (vi and emacs) as we were sometimes pairing remotely.

                                                                                        Remote pairing was easier in some respects. Instead of using one person’s machine, which could have its own config issues, we spun up a VM on AWS from an image we made, so there was a standard base configuration.

                                                                                    2. 4

                                                                                      I would be interested to know if the authors team consistently concludes during regularly scheduled retrospective sessions that everyone enjoys doing forced pairing enough to keep it a thing.

                                                                                      Pairing was already a part of the culture when I originally joined, so it was actually pretty hard to get people to admit they didn’t enjoy it (politically unpopular). It was never brought up in retrospectives. That said, I’d say the majority of the people who worked there did enjoy it and it worked well for them.

                                                                                    1. 4

                                                                                      I’ve paired full time for the last five years on complex banking software - I’d say unless you’re doing simple CRUD, it’s more like “pairing, take the productivity of two devs and multiply it by 4”.

                                                                                      Every developer gets to work in the whole system - no silos. Everyone gets to learn everyone else’s tricks and tips - no slow fuddy-duddy who still doesn’t know about Ctrl-c, etc.

                                                                                      Not only that, but pair rotation means we see no burnout on really hard tasks and tech debt. Normal companies I’ve worked at only have the stamina for either minor tech debt or “scrap it and start over”. Both are terrible choices for long term productivity. The real value is in massive tech debt projects accomplished over months, without a loss of functionality or features. Pairing enables that where single developers just can’t handle the boredom.

                                                                                      Also, pairing is a skill that is as separate from programming as touch typing. It needs to be learned and practiced for months to see an ROI. Most people don’t have the chance to try it for that long, so they remember it with as much fondness as someone with a few weeks of typing remembers the keyboard ;)

                                                                                      1. 1

                                                                                        I respectfully disagree.

                                                                                        I specifically wanted to avoid the conversation of productivity (happiness is a more humanitarian metric, and therefore more important to me), but here we go:

                                                                                        I’ve paired full time for the last five years on complex banking software - I’d say unless you’re doing simple CRUD, it’s more like “pairing, take the productivity of two devs and multiply it by 4”.

                                                                                        I was pairing on a payment gateway, so similar problem space (not easy). I found no such productivity multiplier. In fact, I was frequently (and silently) bemused when I noticed “odd” programmers completing far more work than their pairing counterparts. I’m still amazing that people try to say that dividing your work-streams in half yields higher efficacy. The math just doesn’t add up here, even in a world where everyone learned by watching people code.

                                                                                        Not only that, but pair rotation means we see no burnout on really hard tasks and tech debt. Normal companies I’ve worked at only have the stamina for either minor tech debt or “scrap it and start over”. Both are terrible choices for long term productivity. The real value is in massive tech debt projects accomplished over months, without a loss of functionality or features. Pairing enables that where single developers just can’t handle the boredom.

                                                                                        You’re creating a false dichotomy where you can choose between pairing or tech debt. Tech debt is equally prevalent in both XP and non-XP worlds. Also, anecdotally, I am living proof that burnout is possible with pairing. :)

                                                                                        Also, pairing is a skill that is as separate from programming as touch typing.

                                                                                        No argument here!

                                                                                      1. 8

                                                                                        Wonderful talk. Considering I use both Node and Go the first bit was hard to take, but totally understandable. I have often met professional programmers that don’t really care about how anything they use actually works. As you said, the only way to really learn is to forge ahead and attempt an understanding of whatever’s inner-workings.

                                                                                        1. 4

                                                                                          A good way to learn, which schools seem to mostly ignore, is to repair something which is broken. I guess they assume you will come across enough of your own bugs, but guaranteeing that the students see certain kinds of failure is useful for making specific points and showing specific interactions.

                                                                                          Plus, the detective mentality is useful on its own and should be fostered wherever possible.

                                                                                          1. 6

                                                                                            My favorite programming course in school was Software Engineering 2.

                                                                                            The first SE course introduced us to working as a team, using version control, unit testing, and documenting our work. But we got to do all this while starting from scratch, which is an uncommon luxury.

                                                                                            The second SE course was centered around refactoring. Every team was provided a particularly bad SE1 project from a few years back. Ours was a checkers app written in Java with Swing. The code was just awful. Instead of matrix or even a 1D array, the authors had created individual JButtons 1 through 64 for the main gameboard. Buttons were their own ActionListeners. It was a dumpster fire.

                                                                                            The challenge of the SE2 project was that you could only refactor some of the app. You weren’t allowed to throw the whole thing away and start from scratch. Plus, bad as the code was, it did work.

                                                                                            We ended up using the newly learned Adapter and Proxy patterns to add multiplayer support to the app. It was pretty fun! And my earliest taste of what actual programming work is like.

                                                                                            1. 2

                                                                                              Back when I was in Uni, our department (mechanical physics) sometimes received crank letters with over-unity devices, etc. I thought it would be fun to have a question in a test to determine why such a device wouldn’t work.

                                                                                            2. 1

                                                                                              I have often met professional programmers that don’t really care about how anything they use actually works.

                                                                                              Do you meet the other kind at all? I tend to use sentences starting with “I have often met” for things like not liking triply-nested expressions. For not caring about how dependencies work, the situation seems bad enough that I tend to say: “I’ve heard in distant lands of the odd savant who understands some internals of their dependencies more often than not, but of course everyone can’t hope to meet such a person themselves.”

                                                                                              At best I meet people who understand the internals of some single project that they are active with the community of. But while they may have poked around inside Vim, they’d know nothing about their network stack or browser or compiler.

                                                                                              This assumption is kinda central to my life, so if I’ve just been really unlucky I’d really appreciate pointers on where to find such people.

                                                                                              1. 2

                                                                                                The risk of a deep understanding of an entire stack is the switching cost: what happens when that library falls out of fashion, the new company only uses X, or you switch to a new language to keep up with the changing times. In my short career I’ve gone through:

                                                                                                • Windows XP+Vim+Perl
                                                                                                • RedHat+Emacs+PHP
                                                                                                • Windows 7+Eclipse+Java
                                                                                                • Suse+ZendStudio+PHP
                                                                                                • Windows XP+VS+VB.NET
                                                                                                • Windows Server 2012+Rider+C#+F#+Vim+Java+Js

                                                                                                That’s an incredible amount of memorization just for language and library basics. I suspect I’m lower than the average. I don’t think it’s humanly possible for me to dive deep on all those things and still get work done. I also don’t have any motivation to try when it’s just as likely my next job will be in OpenBSD Klingon edition.

                                                                                                1. 2

                                                                                                  I currently work with a really awesome lead programmer that pushes understanding rather than spouting meaningless platitudes. Still, teaching is a challenge. Things are easier for her to grasp, and her code reviews lean toward style more often than not. Nevertheless, I feel like I’ve improved professionally by seeing her work and speaking to her.

                                                                                                  Whereas, at my previous job I had a coworker that was a “lead” in the business for nearly 10 years. I really don’t think he could code a loop on the fly. It was strange. It was depressing. Yet, he has survived by being one of those programmers that can’t program. It was not something I wanted to grow into. I’m glad I have the pleasure of working with people that seek to build maintainable codebases. Add to that the fact that they also desire to understand how the tools they use work.

                                                                                              1. 5

                                                                                                I’ve been pairing full time for five years. Having trained 12+ developers in that time, I can say with confidence that pairing is a unique skill that takes most people about 6-12 months to improve from “below average” to “above average”. I’d liken the difficulty to learning to touch type the first time.

                                                                                                Having put a lot of time into practicing the skill, right now I prefer to pair on most problems. I also prefer to use Vim, use TDD for most problems, and touch type. None are required to accomplish good work, but having the tool in the toolbox (with time invested to learn it) means I can judge for myself when the tool is appropriate to use.

                                                                                                Likewise, I’ve yet to see any believable research into programmer productivity. It’s currently impossible to measure, any studies are small sample sizes on the least possibly trained cohort (often times university students). As much as I want to believe in any study either way about TDD, pairing, static types, agile, new languages, etc, they are all just guesses made with anecdata and the fashion of the day. At least accepting the reality of the situation will let us tackle the real problem: why is programmer productivity impossible to measure?