[HN Gopher] Reading code is a skill (2020)
       ___________________________________________________________________
        
       Reading code is a skill (2020)
        
       Author : historynops
       Score  : 90 points
       Date   : 2021-09-20 20:25 UTC (2 hours ago)
        
 (HTM) web link (trishagee.com)
 (TXT) w3m dump (trishagee.com)
        
       | AshamedCaptain wrote:
       | I have found that learning a bit how to read assembly code (for
       | reverse engineering) actually helps your "reading code skill".
       | It's practically the same thing except 1000 times worse: the
       | dissassembled/decompiled code has absolutely no syntax sugaring
       | of any kind, so you have to rely on strictly your experience and
       | pattern matching to be able to efficiently guess what this
       | snippet is trying to do. If you can do that, you can probably
       | read the most awful of (regular) codebases.
        
       | tacker2000 wrote:
       | In my opinion, modern IDEs, where you can navigate around by
       | clicking on functions and objects and also have the API docs
       | integrated have greatly improved the time of understanding a
       | codebase.
        
         | fridif wrote:
         | Agreed, but it never should have been this complex in the first
         | place :)
        
           | tacker2000 wrote:
           | Of course, but i cant imagine any non trivial project not to
           | be complex.
           | 
           | A lot stuff is built without knowing what will come after, so
           | often you will have layers upon layers that need to get dug
           | through. Thats just how software will always be...
           | 
           | I took weeks or even months to understand how the Magento 2
           | (a php ecommerce framework) codebase works, probably one of
           | the most complex codebases ive seen personally to date.
        
           | pm90 wrote:
           | I wonder if its possible to avoid code that is meant to
           | represent real-world business logic from being too complex.
           | In most situations, the requirements of a business are
           | constantly changing and writing code that can express that
           | logic without blowing up in complexity is a really difficult
           | problem.
        
             | TeMPOraL wrote:
             | It's not where complexity lies anyway. The complexity is in
             | the glue code - the layers upon layers of indirection and
             | endless repackaging of the same data. This is where you
             | need all the "jump to definition"/xref functionality, and
             | it's hardly enough.
        
             | zimpenfish wrote:
             | > I wonder if its possible to avoid code that is meant to
             | represent real-world business logic from being too complex.
             | 
             | Yes. But only for the first couple of hours until someone
             | who {missed the meeting, forgot something, didn't check,
             | etc.} comes along with changes.
             | 
             | (Alas, this happened to me over the last two weeks and now
             | the pristine simple logic is a fudged mess.)
        
         | taeric wrote:
         | This isn't exactly an invention of modern IDEs...
         | 
         | The fabled "lisp machines" of way back when could do similar.
         | Most "image based" development environments let you jump to
         | source of objects quite well. Play with the developer tools of
         | your browser to get an idea of what used to be the goal for any
         | dev environment.
        
       | guiraldelli wrote:
       | I just skimmed the article, but a more comprehensive text on
       | acquiring the skill to read code is the book Code Reading, from
       | Diomedis Spinelli [1].
       | 
       | [1]: https://www.amazon.com/Code-Reading-Open-Source-
       | Perspective/...
        
       | lancemurdock wrote:
       | I am in my 2nd year as a FE so still learning a lot. I've found
       | that I am very good at reading other peoples code. I think being
       | self taught and initially starting as a solo founder before
       | entering the professional world helped me greatly in this
       | department.
       | 
       | However, I am not as strong at getting a project going. I've
       | underestimated how long it will take me to do something or missed
       | key parts that should have been thought through. Hoping this
       | chalks up to still being new-ish at my craft and in time I get
       | better at this.
        
       | softwarebeware wrote:
       | I think the people who were posting "learn to write good readable
       | code" weren't disagreeing with the idea that reading code is a
       | skill so much as they were calling out a comparison between:
       | 
       | a) coders who can read bad code and who also write bad code
       | 
       | b) coders who can't read bad code but who write good code
       | 
       | In that case I would always choose to work with person b.
       | 
       | tl;dr I don't think that they were disagreeing but adding on
       | another important point
        
       | theshrike79 wrote:
       | The ability (and willingness) to dive into legacy codebases and
       | make sense of them paid my bills for a good 15 years after
       | graduating with a CS degree.
       | 
       | It was fixing bugs and adding new features to existing code,
       | usually stuff that was 5-10 years old at the least. If I didn't
       | understand something I needed to wait for That Guy to show up.
       | The one who did the first version some time in the last
       | millennium.
       | 
       | Latest versions of anything was a pipe dream. Java version was at
       | least 1-2 major versions behind the time. Business logic was
       | PL/SQL and Perl scripts old enough to have a driver's license.
       | 
       | Also: print-debugging all the way. There were exactly zero ways
       | to attach any kind of modern debugger to a 20 year old pile of
       | code that had organically grown to what it was at the time.
       | 
       | I think I was 16-17 years into my career before I started a
       | greenfield project from scratch, one I could decide the full tech
       | stack from top to bottom.
        
         | aprdm wrote:
         | One of the systems I work with just re-hired the original
         | developer now that he retired. The software is around 20 years
         | old and the guy is working for fun. It's actually quite
         | interesting to see haha, the system is the core of a large
         | company and hasn't changed that much since he left a decade
         | ago. He sort of picked up from where he left.
        
         | dboreham wrote:
         | The prevalence of people who like to generate "write-only" code
         | bases keeps this business model alive and well.
        
         | armchairhacker wrote:
         | > Business logic was PL/SQL
         | 
         | Funny that you said that because i sometimes hear "store your
         | database logic / invariants in the database!"
         | 
         | I guess it depends what kind of logic.
        
           | theshrike79 wrote:
           | In this case it was decoding binary responses from devices
           | directly off the wire. Completely bonkers setup.
           | 
           | If the PL/SQL parser failed, there goes that message. Oh,
           | well. Try again next day when the message arrives or dial the
           | device and ask it to send it again.
           | 
           | I suggested after a while if we could store the raw message
           | in a queue table and parse it from there. But no, everyone
           | was too scared to change the system and we stuck to the old
           | ways.
        
       | hosh wrote:
       | I remember reading a much older article posted here. The author
       | recounted his time working with two different coders, and how he
       | admired and respected each of them.
       | 
       | One was very skilled at reading code. That skill didn't just help
       | him with being able to understand easy to read code, but also to
       | understand difficult to read code. This allowed him to go through
       | the tech stack to find out what is wrong.
       | 
       | The other was very skilled at writing readable code, and more
       | importantly, structuring its abstractions and interfaces just
       | right. The primitives provided were exactly what he needed.
       | Sometimes, when he wanted to expand the functionality, he finds
       | out there were already primitives he can use for that expanded
       | functionality.
       | 
       | It's not like you can't do both, but they are distinct skills and
       | useful in different ways.
        
       | shadowgovt wrote:
       | This is a great take on the topic, but it doesn't dive into the
       | topic itself.
       | 
       | What are some techniques you've found help with reading code?
       | 
       | I'll start: breaking out trickier bits into isolated units and
       | testing them to confirm my hypothesis. This gives me two pieces
       | of information: it tells me what I do and don't understand about
       | the unit I'm looking at, and it tells me what I don't yet know
       | about the unit's dependencies (because to do a mechanical unit
       | test, I need to mock / fake those deps, so now I know what
       | assumptions I've made about those deps). This is useful for code
       | with some very esoteric pieces in it (I spend a lot of time in
       | graphics-land, where people do bad things to bit fields with
       | equivalent meanings with the goal of saving a CPU cycle or two).
        
       | Hermel wrote:
       | That's why I prefer testing code comprehension skills over
       | testing code writing skills in interviews. In my experience, the
       | former is much more indicative of job performance than the
       | latter. I don't understand why code comprehension tests aren't
       | more widespread.
        
       | JohnBooty wrote:
       | The only thing harder than "understanding bad code" is
       | "explaining to your manager why you're going to need oodles of
       | time to accomplish simple things because the code is bad."
       | 
       | I've been in this industry for a couple of decades and I'd
       | consider sacrificing a limb if the latter could somehow become
       | easy.
        
         | Waterluvian wrote:
         | Agreed. Two comments:
         | 
         | 1. I've had some luck using the "I have to clean the work site
         | before I can assess the situation" analogy.
         | 
         | 2. I've learned to refactor bad code as an effort to learning
         | it, even if the refactor is not going to be pushed into the
         | codebase. For me this is the best way, by far, to figure out
         | messy code.
        
       | olah_1 wrote:
       | Hardest part of reading code is knowing where to start. I wasn't
       | around at this point, but I can only imagine the horror of a C
       | programmer seeing their beautiful art broken apart into a bunch
       | of nonsensical files in C++.
       | 
       | I like that Golang started to undo some of this issue of hundreds
       | of little files that jump all over.
        
         | jcun4128 wrote:
         | where is main... ha
         | 
         | Yeah I'm trying to work on something for visual code navigation
         | and also project management just a brain fart but yeah.
        
         | Jtsummers wrote:
         | > I can only imagine the horror of a C programmer seeing their
         | beautiful art broken apart into a bunch of nonsensical files in
         | C++.
         | 
         | C uses multiple files as well.
        
       | antirez wrote:
       | I think that you can't get as good as you would like to be at
       | reading code: if you are a good code _writer_ , then there aren't
       | so much improvements you can get to your reading skills. Bad code
       | will resist to such skills anyway, because bad code is full of
       | that-bad-code-specific lack of modularity, interfaces, unexpected
       | side effects and dependencies and so forth. You can only get good
       | at reading better "locally", and you can get better at
       | "navigating". But the complexity is in the global architecture
       | and its errors, so you will have to dig, understand what's going
       | on, what code matters, what is dead, how apparently unrelated
       | things actually affect each other. So what I believe is the key,
       | is exactly what somebody replied to the tweet mentioned in this
       | post, that is: learn to write simple code, it is the real point
       | because most of the time you read your own code, fortunately.
        
         | barrkel wrote:
         | > because most of the time you read your own code
         | 
         | This is just not the case in most software engineering jobs
         | outside things like startups where you're on the original team,
         | or your pet project.
         | 
         | In a team amongst other teams, you'll be reading code that you
         | need to integrate with, reading colleagues' code when
         | reviewing, and generally be producing much less than the sum of
         | the code produced by everyone else on your team and your
         | dependencies.
         | 
         | If you're the single owner of a component or subsystem, then it
         | can be true, but that's not normally healthy for a software
         | company - it implies a low bus factor.
        
           | antirez wrote:
           | You can read "your own" also as "you own team/group/...", and
           | you as a group can have standards and quality checks on how
           | to write good code. Especially the initial architecture of
           | every new big system should be scrutinized with care to avoid
           | starting with a spaghetti-system from the scratch that will
           | hardly get better. And of course: coding standards for all.
        
           | xmprt wrote:
           | Bus factor meaning the number of engineers who would have to
           | die in a bus crash for the company to stop working?
        
             | frosted-flakes wrote:
             | That works too, but the saying is "hit by a bus".
        
         | atomicity wrote:
         | The author seems to be say in the article that writing readable
         | code, at least for yourself, is still an important goal. I
         | think they are arguing against why a writer shouldn't be
         | expected to take it further.
         | 
         | For example, should a new grad be able to read your code
         | without help? Should a 5 year old? At some point, you are
         | spending more time writing design docs, refactoring the code,
         | simplifying the tests, and gathering learning resources than
         | you are just writing code that works.
         | 
         | Newer engineers rarely hear about how much they need to learn
         | to read good code, and how much disagreement there is about
         | what good code looks like. As a result it is easy to get into
         | the mindset that "surprising" or "complex" code is bad.
         | Instead, it would be a lot better if engineers are encouraged
         | from the start to see reading code as a challenge. Nobody
         | starts off knowing grep, folder organization conventions, go-
         | to-definition shortcuts, and architectural design patterns
         | needed to understand certain pieces of code.
         | 
         | To improve yourself, you are better off focusing on writing
         | code, but at the organizational level, it's better for the team
         | if people are willing to assume that reading code and writing
         | readable code aren't an easy tasks.
        
         | mmcdermott wrote:
         | I tend to agree with the original author more than the 'git
         | gud' remarks for the reasons generally stated. It is important
         | to learn to write better code, but the world will always be
         | full of bad and learning to cope will always be valuable.
         | 
         | I did find that I was able to use my code writing skills to
         | bootstrap the code reading skills. If there was code that
         | struck me as obtuse, I would try to refactor it. Sometimes I
         | found that the code really could be written more simply.
         | Othertimes I found that I had missed something important about
         | what was going on. As I did this, I learned to better intuit
         | what the original authors probably meant and where to look for
         | confirmation/rebuttal.
        
         | Jtsummers wrote:
         | Yep. There is a limit to what bad code, just like bad prose,
         | can tell you without having to restructure it yourself or risk
         | losing your sanity to discover in the existing presentation.
         | I've had colleagues whose code was totally functional and
         | worked to achieve the desired result, and totally
         | incomprehensible without a great deal of effort. Rewriting and
         | reorganizing into a more sensible flow (aka, refactoring) was
         | the only way to discern the real meaning behind the code. Code
         | reviews are helpful here, to keep code like that out of
         | production and give feedback so less code like that gets
         | written in the first place.
        
           | refenestrator wrote:
           | Today's code-reviewed perfection is tomorrow's mess, unless
           | you refactor as the domain drifts away from the original
           | model.
           | 
           | Code reviews can only enforce existing practices and style,
           | rethinking architecture is a different matter.
        
         | refenestrator wrote:
         | > because most of the time you read your own code
         | 
         | I think this is probably more true for you than it is for us
         | corporate schlubs :)
         | 
         | For those of us with less talent at writing a unique piece of
         | code, the process of diving in and figuring out a mess is
         | actually a learned skill that we get better at over time,
         | possibly the most important one.
        
       | gHosts wrote:
       | Read actively.
       | 
       | * If you have a working hypothesis as to what the code is doing,
       | state that hypothesis as a comment.
       | 
       | * If you think you know what it is doing, making that comment
       | executable. ie. put in an assert. Better an assert punches you in
       | the face than you rely on an incorrect analysis.
       | 
       | * If you don't know WTF happening, or not sure, turn that comment
       | into observability, add logging or something.
       | 
       | * Make microcommits using rebase or the like, add observability,
       | add asserts, add unit tests, add refactorings, make behavioural
       | changes.
       | 
       | * Do only one thing per commit, makes review and test much
       | easier.
        
       | zwieback wrote:
       | There's the basic hygiene of writing code: naming things, adding
       | the right amount of comments, letting the compiler do the
       | optimizing whenever possible.
       | 
       | However, I find that writing reusable, highly modularized code
       | sometimes comes at the expense of readability. In the olden days
       | I wrote what I would call horizontally layered code with
       | relatively clear path of execution but that leads to highly
       | interdependent modules. Object oriented code or code that uses
       | lots of dynamic resolution of call sites makes code reading much
       | harder. Multi-threading, at least the traditional kind, adds more
       | trouble to figure out what happens when just by looking at the
       | code.
       | 
       | I think that's why patterns are important: if we give things
       | names people broadly agree on it's much easier to piece together
       | how different parts of the code should interact.
        
       | passivate wrote:
       | Is there any agreement on the meaning of 'readable', besides the
       | obvious of write it like I would?
        
         | willmorrison wrote:
         | I think there are some basic measures of readability that could
         | be quantified. Off the top of my head, the ratio of keywords to
         | symbols and the density of those keywords/symbols would make a
         | difference. Seems like it can be specified and not just left at
         | "is it written like I would write it," but I can't think of any
         | other metrics right now.
        
       | bit_logic wrote:
       | Reading code should completely replace all the coding portions of
       | current technical interviews. There's a lot of issues with
       | writing code under interview conditions, many tech interview
       | threads here and other places have covered this. Reading code
       | avoids all those problems. And if someone can explain well what a
       | piece of code is doing, then of course that person can also write
       | code. How can you read without knowing how to write? And reading
       | code also allows showing the depth of experience much easier in
       | an interview setting. For writing code, the leetcode answer from
       | a junior or senior is going to look exactly the same. But while a
       | junior and senior may both adequately explain what a piece of
       | code is doing, a senior can show more of their experience by
       | discussing how it could be improved for readability, maintenance,
       | and other engineering factors.
       | 
       | Reading and writing are two sides of the same coin. So why not
       | test for the side that works much better for interview conditions
       | and also allows more signal between a junior vs senior levels of
       | experience?
        
       | didibus wrote:
       | Thanks for articulating something I've always tried to tell
       | others.
       | 
       | Yes, writing readable code is preferred, but as an individual
       | developer, you can't just wait for others to make their code
       | readable before you're able to understand and contribute to it,
       | you need to work on your skill of reading code, even badly
       | written code that is unreadable.
       | 
       | There's also another dimension I think people often overlook,
       | don't just write readable code, write easily extendable,
       | modifiable and testable code.
       | 
       | Having code that very clearly explains that it has a shared
       | global that is manipulated and touched by each component doesn't
       | really help with the task of adding or changing a feature without
       | breaking anything else or taking forever to do so, because of
       | having to touch too many things in the process.
       | 
       | And what's counter intuitive is that writing simple well designed
       | code may actually make it harder to read, if you're not aware of
       | the patterns or constructs that are leveraged to allow the code
       | to be designed so it can be easily extended, modified or tested.
       | 
       | For example, you might find using Java streams to be harder to
       | read than a for-loop. You might find dependency injection harder
       | to follow than just creating new resources wherever they are
       | needed. You might find using some DSL for templating harder to
       | read than just doing your own string concatenation, etc. That is,
       | until you learn about the patterns and constructs and become
       | familiar with them, and good at reading and understanding them as
       | well.
       | 
       | That's why I would say the most important things are in that
       | order:
       | 
       | 1. Get good at writing extendable, modifiable and testable code.
       | That means, code that can be extended, modified and tested
       | quickly with low risk of breaking other things and requiring
       | minimal code changes in the smallest number of places.
       | 
       | 2. Get good at reading code, both bad messy code with poor names,
       | no consistency, and complicated designs and abstractions (this
       | includes learning tricks to explore such code with logs, prints,
       | debuggers, leveraging IDE features, etc); as well as good code
       | that uses more advanced patterns and language features you don't
       | yet understand very well.
       | 
       | 3. Get good at making the code you write readable, that means
       | clear intuitive names, useful comments, proper formatting,
       | consistent patterns, not abstracting beyond what is relevant,
       | stay close to the problem, etc.
        
       | kragen wrote:
       | Gee has excellent points.
       | 
       | I think that in order to get good at writing readable code, you
       | need to spend a lot of time both reading code and watching other
       | people read code you wrote. That's the way you learn which things
       | make code hard to read or easy to read.
       | 
       | In fact, I'd go further and say you need to watch _people in your
       | target audience_ read code you wrote. Different subcultures find
       | different styles easier or harder to read. When you 're writing
       | prose, you always have a target audience, and readability is
       | relative to that audience. The same is true of code.
        
       | a_c wrote:
       | Good code all looks the same. Modular, name what you meant, clear
       | boundary, relevant stuff got grouped nearer.
       | 
       | Bad code is each bad in its own way. There are just infinite
       | combination of bad. Good luck on that. It is like telling kids
       | what _not_ to do. They still won 't behave. It is like bring
       | people with an "unfit culture" to your team. You might be able to
       | work with them, you might be able to change them. But you also
       | only got so much time
        
         | pm90 wrote:
         | > You might be able to work with them, you might be able to
         | change them. But you also only got so much time
         | 
         | Recognizing this tradeoff explicitly might go a long way in
         | improving how we approach the issue of training engineers. On a
         | certain level, anyone motivated to do so can learn software
         | engineering. But the amount of mentorship required differs
         | significantly. And personally I'm not against doing that, but
         | when organizations don't allocate time for intensive
         | pairing/mentorship but expect senior engineers to somehow find
         | time for it is what doesn't really work.
        
           | a_c wrote:
           | > but when organizations don't allocate time for intensive
           | pairing/mentorship but expect senior engineers to somehow
           | find time for it is what doesn't really work.
           | 
           | All organization has their own flavor of culture. Visionary
           | vs mercenary, waterfall vs collaborative, explicit vs
           | implicit. One can design/shape their organization to favor
           | explicit knowledge sharing. I agree with you that it is a
           | trade off. Just that all else being equal, I think writing
           | good code offer way more leverage than getting better in
           | reading code, knowing that they are not mutually exclusive
        
         | tessierashpool wrote:
         | I enjoy a good literary reference as much as the next person,
         | but this just isn't true. It isn't even true for closely
         | related languages. Good Clojure doesn't look anything like good
         | Common Lisp. Good Elm looks nothing like good TypeScript. Good
         | Python doesn't even look like good Ruby.
        
       ___________________________________________________________________
       (page generated 2021-09-20 23:00 UTC)