[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)