Hacker News new | past | comments | ask | show | jobs | submit login
Reading code is a skill (2020) (trishagee.com)
155 points by historynops on Sept 20, 2021 | hide | past | favorite | 89 comments



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?


>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? [...] Reading and writing are two sides of the same coin.

I'm not so sure about that. I can read assembly code but I can't write it at a competent level that an employer would require. Reading code is often easier than writing it.

Maybe an analogy is reading vs writing a movie script. A lot of us can read the actors lines and set directions and can then explain what the movie is about -- but most of us are not skillful enough to write a movie script.

The deciphering-vs-generation divide happens in human languages too. Many times, a person learning a foreign language can understand what someone is saying but if asked to generate a sentence to express a thought, they often will be flustered and halting in their speech as the brain struggles to find the next correct word to say.

The reading vs writing skills don't seem to progress equally.


Similarly, it took a few months of learning to read Haskell before I felt comfortable writing more than just a couple lines.

I like the idea of code reviews in an interview though! Seeing how someone approaches a new code base would be a really pragmatic way to evaluate them. Having them make a targeted change to a smallish unfamiliar program would be informative as well.


Makes sense, It is also easier to read and understand a book than it was for the author to write it. You can also think you understand something while you read it and later realize that you misunderstood it.


In short, it takes a longer time to read code than to write a simple snippet.

Because you may not know the syntactic sugar syntaxes while being an expert at the language / field. They also may not know libraries that's been used by the code without researching beforehand.

OTOH, stripping the code to read from libraries and syntatic sugar syntaxes will reduce the code quality and sometimes making it harder to read / maintain. It doesn't reflect your tech stack in the company.

While writing code will guarantee that it's something the interviewee knows, with tolerable typo and syntaxes, and IMO it's more suitable for the interviewer to ask for written code than vice versa.


And if someone can explain well what a piece of code is doing, then of course that person can also write code.

I can read and understand many mathematical proofs and explain why it's true, but I could never have proven it myself. I can read and understand most of the great novels ever written, and even try to explain their greatness, but I could never have written any of them.

That being said, I agree that listening to someone explain and critique written code probably gives at least as good insight into their coding ability as having them whiteboard a leetcode problem.


I feel like this is a bad analogy. Mathematical proofs often require some deeper insight that is being communicated. While this can be applicable to code, this is in the space of inverting a binary tree type questions.

Most code we're writing is more akin to seeing if you can read a newspaper.


One of the best interviews I've had involved coming in and just sitting with the lead dev and we then spent an hour grabbing a fairly low hanging bug that was in their system and he just had me drive and allowed me to ask questions about the folder structure or conventions they used.

He could see I understood how software worked, could reason about their style and approach, and I could fix the issue. I learned about their style and approach and got at least a feel for if their code base was going to be a nightmare or not.

With that said... it's hard to time your hiring interviews with when you have outstanding bug tickets that you can time box to an hour or two and don't require so much esoteric implementation details that it's a waste of time. Koans are GREAT but they do fall short on being a piece of the project that the applicant will be working on, so you miss out on seeing how the applicant reacts to your codebase and he misses out on sticking his toe in it.


I use code reviews in interviews for a similar reason.

If they're not able to critique the code and explain what it's doing, why it's changing, and what a better option might be they're going to struggle working in our environment where code reviews are emphasized as a huge part of the SDLC and not just the rubber stamp at the end.


Well said. Jr Devs almost always face pre-existing code bases. All college courses have undergrads always starting from scratch for their project. Simply put one of the things they are least experienced with is reading someone else's code.


Completely agree. I have interviewed and hired a number of people and a simple one page reading code test (“What do you think the code does and are there any bugs?”) worked wonders.


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.


The prevalence of people who like to generate "write-only" code bases keeps this business model alive and well.


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.


> Java version was at least 1-2 major versions behind the time

A lot of shops are 9 versions behind right now.


Yea, this was in the ye olden days where Java major version were big news. Now they have a major version upgrade every time someone coughs at the office :D


For Java, definitely. Lots of places are still on Java8.


> Also: print-debugging all the way. There were exactly zero ways to attach any kind of modern debugger

That's just laziness from the original developer. To me, no debugger support means it's time for a re-write.


Yes, please tell me the argumentation you would use to completely rewrite a 10 year old perfectly working stack, which is actively used to read tens of millions of devices of varying age daily. A piece of software that has around 50 coders on it actively keeping it running and adding new features and supported devices.

(It took around 5 years and a team of 20 with millions of funding to "rewrite it" eventually and even they had to drop support for all but the latest devices. The old system is still chugging away, reading the old devices)

Also I would like to know how you would attach a debugger to a stack that contained, among others, ASM/C-code running on an embedded device on the other side of the world, some MFC/C code on a gateway windows computer, perl scripts running god knows where and a PL/SQL bundle on an Oracle server in another country and some Java logic on a different server.

This is the life legacy coders live.

Of course, if you have a modern stack you can just click "debug" on your IDE and it'll automatically attach to a remote process and let you step through the code. We don't have that :)


> Also I would like to know how you would attach a debugger to a stack that contained, among others, ASM/C-code running on an embedded device on the other side of the world, some MFC/C code on a gateway windows computer, perl scripts running god knows where and a PL/SQL bundle on an Oracle server in another country and some Java logic on a different server.

That sounds incredibly brittle. But each of these components should be debuggable individually and have a well defined interface.


"should"


Exactly my thoughts as well


> That's just laziness from the original developer. To me, no debugger support means it's time for a re-write.

when do you plan to get started on the linux kernel? that Linus is a lazy pri*k, he'll never get to it!

*printk

https://www.kernel.org/doc/html/latest/core-api/printk-basic...


There's also KDB and KGDB (he eventually conceded that having a debugger in the main tree was for the best).

https://www.kernel.org/doc/html/v4.16/dev-tools/kgdb.html


> 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.


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.


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.


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.


> 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.


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.


> 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.

Your typical company has a bus factor of 0, having one programmer who knows the code seems like a huge improvement over that.


Bus factor meaning the number of engineers who would have to die in a bus crash for the company to stop working?


Companies never stop working like that, they just stop being able to make changes. So many companies has huge amounts of legacy code nobody understands and they still work, that is what bus factor 0 looks like. It isn't the end of the company but it is the end of any significant innovations the company can do with that product.


That works too, but the saying is "hit by a bus".


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.


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.


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.


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.


> 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.


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.


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.


I prefer the "let's clean the kitchen first, before trying to cook new dishes"


If the manager isn't technical or won't understand, that's a red flag for the org/company.


I wish I shared your optimism.

At this point I think it is a red flag, even if your manager DOES understand.

Because chances are THEIR manager won't understand. Or their manager's manager. Etc. You will look bad no matter what.

At this point I am beginning to think it is basically a no-win situation. No matter what.


> Because chances are THEIR manager won't understand. Or their manager's manager. Etc. You will look bad no matter what.

Maybe that's why FAANG and top 5 capitalizations all have former engineers as CEO.


(Maybe "no-win" is not literally true. In a literal sense, I suppose I really mean: "Dismally low odds of winning, best not to get into such situations")


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.


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/...


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


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


> 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.


> 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


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.


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.


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.


I think tools like Omnisharp have greatly improved what and how IDEs can do for developers. It’ll tell you memory allocations, boxing, expensive operations, instance usages, dangling disposables, etc. It leads to cleaner, more performant code in my experience.


I mean, I do like comprehensive tooling. I don't like pretending some of the older commercial tool chains didn't exist.

And much of the modern set is heavily enabled by massive compute and memory. Such that often, it isn't that the checks you are talking about couldn't be done. They were often pushed to dedicated build sessions. Which often got skipped by developers.


Agreed, but it never should have been this complex in the first place :)


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.


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.


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


I think this is an argument for less developers on a project, or at least more services owned by less developers.


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.


The question nobody asks is if some code is even worth reading.

I recall a project that was offshored where a local team was later asked to add functionality to it.

The code was so bad, it was useless to read it. The execs who decided to outsource in the first place did everything they could to get the local team to build on top of what they purchased. Finally, they brought in a very expensive consultant who told them flat out the only way he was going to touch it was a total rewrite. People were furious. In the end, he won and it ended up being a complete rewrite completed faster than the initial offshored project. For half the price.


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.


> 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.


Some codebases have many thousands of files. And some of these projects are very readable. Properly factored code is readable because of its structure, well considered abstractions, and conceptual locality, not from being placed into a small number of files.

In any event, I don't know how language choice has much to do with this.


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.


Yeah "main", which contains 5 lines. So you gotta find where the real action is and down the rabbit hole you go.


Yeah if you're lucky prev/current dev can give you an overview how it flows/works.


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.


Is there any agreement on the meaning of 'readable', besides the obvious of write it like I would?


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.


Some additional general comments:

- Avoid deeply nested code; try to reduce "cyclomatic complexity". Refactor to use helper functions and guard statements as appropriate.

- Your code shouldn't need an IDE to be understood. Among other things, this often means avoiding overuse of type deduction features like auto in C++, var in Java, etc.

- A well-named function can be treated like a black box, without having to dive into its implementation to figure out what it's doing.

- Simple is better than clever. For instance, just because you see an opportunity to use the Y combinator (https://en.wikipedia.org/wiki/Fixed-point_combinator#Fixed-p...) or Duff's device doesn't mean that you should.

- Avoid premature optimization. Only reach for it if it's proven to be a bottleneck, preferably with real-world data (as microbenchmarks are not always representative).

- This one comes up most frequently in code review, and is probably the most important one: if your colleague doesn't understand your code, it might not be readable.


While those are great points (thanks for writing them BTW) I do wonder if we need to have a more wide-scope approach to the various styles of code. Quoting the article

> Code that's hard to understand is often a result of an accumulation of things:

> The code was written at a time when the language/framework didn't do then what it does now;

> The code was written a while back and the fashions and "best practices" back then were different;

> Each line of code was written with readability in mind, but over time as more lines got added, the overall message was lost;

> People moved on and moved away, and now you haven't got anyone to ask about the business or technical reasons behind something (and of course the documentation is horribly out of date).

I would add:

> The code was written to meet a budget for time/latency/size and readability became secondary to meet those requirements. E.g. systems code/firmware/OS code often have a hard limit that they need to comply with. I've had to write code for an earlier job that had to fit within 16kb - compiled, and the code was anything but readable.


Oh, that's definitely valid.

It's not like your colleagues set out to write bad code, or built systems that weren't extensible (at least, I hope that's the case). But they needed to get things done, and so they did what made sense at the time.

And over time, these organically-grown codebases develop more and more complexity and tend to retain historical baggage (often fueled by "if it ain't broke, don't fix it" coupled with reward structures typically not incentivizing the repaying of technical debt).

(not referring to your colleagues per se, but rather another general statement)

A popular fable is that of Chesterton's Fence. In short: if you don't understand why something is the way it is, then you should be wary of getting rid of it. This is incredibly applicable to refactors and clean rewrites.

Starting with a good foundation is crucial, since a lot of code is inevitably patterned on surrounding code. But making sure those incremental changes over time are also of high quality is important for making sure that the code quality doesn't degrade over time, because the new code of today is the existing code of tomorrow.

I sympathize with stringent product requirements -- that imposes tons of limitations on what you can reasonably do. But if you have nothing else, a comprehensive, well-structured, well-documented (and/or self-documenting) test suite can be an excellent way to document system behavior.


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.


Can someone please explain to me what it means to "read code"? I feel like the article said I should do it yet didn't explain what it is and how to do it.

To me, it appears a meaningless phase, like saying "think harder". It's something said in a good faith effort to be helpful, but unfortunately isn't. I wonder if the "meaning" is intended to be something like, "learn to understand code"? Yet that replacement isn't any more helpful. Can code be understood broadly? I don't think to can be.

I had a boss once who tried to emphasize, "you have to learn to read code". Some of the things he wrote were comprehensible to me, some not. He was a senior and I was a junior. He also once said to me, "I don't get what's special about Lisp". When I tried to explain about macros and metaprogramming, he said "but Python has decorators". I assume my boss could "read code". He could certainly write it, he demonstrated an ability to explain the workings of a new codebase, and claimed he could "read code". Yet he appeared to be lost about how Lisp macro programming differed from Python decorators. I could have explained it better. Regardless, this tells me that "reading code" is non-transferrable. So, maybe "read code" is meant as a shorthand for "develop mastery within the language at hand so that you can quickly understand new code presented to you". Again, I'm failing to see how this is helpful, actionable advice. No matter which way I try to understand it, "leatn to read code" feels like it amounts to being told "be more experienced".


Reading code in one paradigm doesn't necessarily transfer to other paradigms


Reading code in one language in one codebase often doesn't even necessarily transfer to other codebases in the same language.

I find this particularly true in academic python codebases and C++ for some reason where single letter variables and cryptic contractions in identifiers is the norm. It's truly a shame that overly verbose java-isms spawned widespread disdain for descriptive variable names - I think one of the easiest low-hanging-fruit to most codebases is just using proper descriptive names for variables and functions, and other updating them accordingly when their meaning or purpose changes.


Absolutely, true, just as reading one natural language won't necessarily help you read another.


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.


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.


There's a concept in soccer of "aggressive receiving". When someone passes you the ball, you don't wait for it to hit your feet. You read the "line" of where the ball is going, and you GET THERE, FAST. Players who don't do this are consistently beat to the ball, or watch passes get by them and land with the other team. There are no "bad passes" in a soccer game, or more accurately, the duty is on a receiver to chase what some might consider bad passes.

Just sharing because it felt relevant.


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.


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.


> favorite movie quotes or song lyrics for average threats

Is it me or is this some terrible advice? Most popular song lyrics could easily fit in a password word list.


One use for https://rosettacode.org/ is to, uh, "consider the readability" of other people's solutions or languages.


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




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: