Ask HN: What code samples should programmers read?
What are examples of code that ever programmer should have read and analysed because they show a particularly deep insight into the problem, a creative attempt at a solution or otherwise outstanding proficiency?
Goal is to learn something from excellent pieces of code, much like it is practised in art by studying Old Masters, pieces of literature or musical compositions.
PS: I admit to exaggeration in the headline / first paragraph ("should have") btw ;)
154 comments
[ 4.2 ms ] story [ 187 ms ] threadFor anyone wondering why this is, here is a good explanation.[2]
[1]:https://www.libav.org/ [2]:http://blog.pkh.me/p/13-the-ffmpeg-libav-situation.html
http://handmadehero.org/
I just can't recommend it enough. All the projects are open source, so you can review the source code and still be walked through the code by book. You'd learn why the programmers made certain trade offs and how the applications became better of for it
Every programmer should read the (presumably open source) code they depend on, but almost nobody does it. Some look at documentation, but not everyone even does that. What you may find is that some of the code you depend on is garbage, and may even motivate improvements.
This may be less feasible for giant messes such as most front-end tooling and frameworks that exist today.
Has this ever been beneficial? I generally just check if a library is popular and maintained and that's always been enough for me. If the code really is horrendous nobody is going to be using it and if you always read the hundred of thousands of lines of code you depend on you'd never get anything done.
When you review a dependency, you answer why it should not be written THIS way. (Or why it's junk and shouldn't be used.)
Length is an important consideration and most never consider it, partly why software is notorious for getting bloated over time. At some point it would be easier to rewrite code from scratch with less complexity and overhead.
It doesn't make it good, but it does mean that it's unlikely to make you ill.
The difference between code and a burger is that anyone can consume a burger but code is consumed almost exclusively by professionals. A better comparison would be power tools where you'll often find that if a brand is popular, it tends to make solid, long lasting products.
To rephrase: PHP is the most widely used server-side scripting language on the web. That does not make it good.
Like what? If you're looking for a JavaScript library for example, you can't really go wrong picking one that has many contributors, an active issue tracker, thousands of stars, lots of forks etc. Unless it's some core part of your stack, I don't see how it's practical to spend a lot of time hunting down super well implemented libraries that aren't likely to be supported in the future because nobody uses them.
> To rephrase: PHP is the most widely used server-side scripting language on the web. That does not make it good.
I'm not a huge fan of PHP but you can still write good software in it.
Libraries are relatively easy to swap out compared to say operating systems and programming languages. Personally I find many of the best libraries tend to be the most popular ones.
To beat the average, by definition you can't just do what everyone else is doing and expect outstanding results. If your problem is unique there won't be a library for it. If you find or create a hidden gem, it's your secret weapon, you are its user and responsible for it.
On the other hand, McDonald's is pretty reliable and you know you're getting something palatable that is probably safe to eat (in the short term, anyway). You don't need to pick the best-in-class library for everything.
There are some rare cases where that makes sense (Keyword: RARE), but most times I've seen developers take that stance, it leads to longer development times, less consistent code, more maintenance work, and generally pretty shitty outcomes.
Popularity is ABSOLUTELY an indicator of things other than just popularity. However you need to understand why the thing is popular and vet that against your needs.
Finally: McDonalds IS good. I don't eat there often, but they provide a consistently satisfactory experience for their customers. There's a reason you can find McDonalds nearly everywhere on the planet.
It's popular to diss on companies that have become large iconic chains, but they're large iconic chains for a DAMN good reason. Plus, they're solving supply chain issues you aren't even considering, much like large popular libraries are handling use-cases and problems you don't even know about.
Can I make a better burger? Sure. Can I make a better burger for the same that McDonalds charges, as consistently as McDonalds does? Fuck no.
The same probably applies to your software.
McDonald's is consistent, predictable, cheap, generic, and ubiquitous. Sometimes those are good qualities. "Good enough" is usually good enough, after all.
Regionally, there are a half-dozen choices that I'll take over McD's: Less iconic world-wide, but as cheap or cheaper, just as consistent, and more pleasing to the palate. I think that's closer to what they were advocating: Not necessarily building it in-house, but also not taking popularity as a reliable indicator of code quality (beyond a bar of minimum acceptability).
>At some point it would be easier to rewrite code from scratch with less complexity and overhead.
I'd agree, and probably wouldn't have commented.
But I think being all of these things:
>consistent, predictable, cheap, generic, and ubiquitous.
Means you have a damn good product. No one is claiming you can't get something better, but come on, I'd love to have software that's consistent, predictable, cheap, generic, and ubiquitous.
If those words describe a popular library, and you decide instead to build your own thing in-house... you better have a really REALLY good reason for doing it.
Note that I never said "consistently good" or "predictably reliable". There are a lot of things in the world that are known to be low-quality, single-use crap that are still everywhere.
> If it hadn't been for the last sentence:[...]
I think it depends on their idea of where "at some point" lies.
A very good reason to write your own software is if the problem is novel enough to warrant it. I'm not advocating that there should be n+1 JSON serialization libraries.
I don't know how helpful reading source is for determining whether or not to use a dependency, but I find it very helpful to have at least a small understanding of how my dependencies work:
1. I find it useful for debugging. If a coworker or I have used a library incorrectly, understanding how the library works can help us figure out why it isn't doing what we wanted. Also, my IDE lets me do step-through debugging through dependency code as well, which can be helpful.
2. It helps with determining the capabilities of a library. If I know how a library works, then I can make reasonable guesses about what features the library has (or could easily add). I find myself thinking, "I'd like to do X, and from what I know of how library foo works, that seems like something it should be able to do." So I can go investigate that.
3. It helps with knowing the performance characteristics of the library. Just yesterday, I needed to implement some stats logic in java. I found an Apache Commons class that does exactly what I need, but by looking at the source code, I found that it uses an O(n) algorithm, which is fine for the cases they are probably targeting. In this case, I need more performance than that, and it's not hard to write this as O(log n). So I wrote my own instead. If my IDE (Intellij) didn't give me super easy access to dependency source code, this would have been more painful.
You don't want to use a data serialization library that is so poorly written that it likely corrupts stuff sooner or later, do you? Or a crypto library that documents almost nothing and requires you to review x86 assembler to find how parameters are actually interpreted cough?
Taking at least a cursory glance at the code is one part of vetting dependencies before using them. Other activities would be:
checking use of best practices ("Your parser written in K&R C is probably fine without fuzzing and any tests"),
availability of documentation ("source is there, no?"),
checking for known vulnerabilities and bugs (First open issue: "Library segfaults when parsing long lines of []{}"),
maintainership ("Last commit: 2004") and
portability ("(void*)a + (int)5.7").
Python's CPickle comes to mind. There's a race condition in there somewhere, but I've never been able to reproduce it with a small program. [1] Using the version of Pickle written in Python works.
This sort of thing is why I'm somewhat negative on the argument that "if Python is too slow, write the important parts in C". It's too easy to break Python's memory model in C code.
[1] http://bugs.python.org/issue23655
Edit: Ah that kind of bug can be ... tricky.
If it corrupts data and has terrible documentation it wouldn't be popular. It's usually very obvious from the community around the library if it's got major problems or not.
If you want to write secure code it's necessary. Otherwise you just end up with PHP web apps that have remotely exploitable memory corruption bugs because the developer didn't understand that he absolutely has to sanitize all user inputs to certain functions.
>If the code really is horrendous nobody is going to be using it
This just makes it pretty clear that you haven't ever looked.
Do you check the source code for Apache, MySQL, PHP etc.?
If I'm picking a library for a component where its flaws would be high impact (e.g. security) and there isn't a strong community behind that library I'm going to be very cautious though.
Python dependencies are source code, not compiled blobs, and the import syntax makes it very explicit where definitions come from.
If I'm unsure how to do something with the library I usually look at the source of the relevant module before looking up online docs.
That said let me add that IntelliJ probably has similar systems.
It also handles downloads via Maven, but I have only done it only once and don't remember the details.
Code is a valuable gemstone covered in layers of shit. Always aim to create diamonds, not CZ, and keep at least one face of that diamond shit free.
I always thought was a very pessimistic way to view code until I landed my first job. Algorithm exercises and toy projects for capstone can be shit free diamonds every time. Working with finicky clients, legacy code bases, and peers who don't care about quality quickly proved that sometimes you're destined to make topaz double-dipped in dung.
Dependencies are no exception to this. I've worked with a mapper that works pretty well out of the box. I ran into an issue with how Strings were mapped to boolean values. It turned out the default mapping values for those conversions were yes, no, y, n, and possibly some other variation of those String values. It didn't include true and false by default.
Basically it expects a parameter along the lines of
codecommit/RepoName/branchName
And then it splits the string and if there are more than 3 items as a result it returns from the function saying invalid value.
I had to correct it to use it myself but I found it fascinating since it suddenly made the somewhat mystical innards of aws seem a little more human. At least that's how I felt :D.
I am assuming you are not a database expert but basing this on the look and organization of the code and not the data structures and design. If that is not true than please share your findings instead of teasing us.
I'm curious would you do the same with your editor (or IDE)? You should see the source code for those behemoths (with the exception of the rewrites like nvim) they are pretty nasty.
Are you going to pick a different editor just because Vim or Emacs (or whatever editor) has nasty code?
Guess what IDE has pretty clean code and is extremely modularized... Eclipse. I can tell you Eclipse is not a comfortable editor (and I use it all the time because I'm used to it not because the code is elegant).
Mature projects often have pretty ugly code but they are mature and stable. Ugly code also doesn't necessarily mean poor design (e.g. if your editor is single threaded and has nice looking code its still single threaded).
I wouldn't imagine it being controversial to prefer well engineered code over less so for bits you will need to depend on.
I would much rather choose a battle tested database that has the features I want, performs well to my testing and profiling than "familiar" looking code. Because good looking code is really more often or not familiar looking code.
So unless the OP is an expert I believe basing the most critical aspect of your application just because the code isn't to your liking is sort of asinine.
Also vim is not flaky. The insides may be a nightmare, but it's very solid.
Mysql and PostgreSQL offer similar functionality, people use both systems for similar tasks. When you try to decide between the two, you find conflicting arguments all over the web. I think in such case looking at the quality of code can be a key signal to help you make a good decision.
I do agree that projects with ugly code can still be extremely useful and in many case an optimal choice, but such project will more likely become obsolete quicker and will cause problems more often than project with high quality code.
It would be pretty low on my check list. The number one for me would be profiling and testing the databases. IMO you should do that first. Even the ability to extend the database with plugins would be higher on my list than code quality (this is for a database). Probably 10 other things would be higher on my list than code quality (again for databases... for libraries thats a different story).
Looking over code would give you more than just an impression of its style; it would also give you a feel for the quality of the product. If most of the code you look at is of poor quality, it is very unlikely that the product, at a high level, will be any better.
So you are going to base the crashing of a database on the cursory non expert runtime of your eyes. Why not just test the database, read the doc, ask other experts.
Secondly rarely do most developers extend their database so their is very little need to know that codebase and they probably should not change that codebase (given the criticalness).
You know what developers extend often... their editors and IDEs. The code quality (in terms of readability) of that should be much higher.
Now obviously if you have nothing but the code to base (like no doc, no benchmarking, no existing mind share, etc...) and are generally knowledgeable in the area than yes code quality would be a good decision criteria but I remind you the OP said it was the major reason between Postgres and MySQL which are probably written by superior experts than the OP.
You look over the source code to decide whether the database is worth proceeding with. I would assume the OP did other research as well, even if code quality was the deciding factor.
And again, I don't find the text editor analogy a compelling argument.
It is hard to map an analogy 100% (after all it is an analogy).
> I would assume the OP did other research as well, even if code quality was the deciding factor.
I wouldn't assume anything about the OP particularly given how poor the original comment was (including not telling what his/her findings were).
I would say his comment implied he went with Postgres. I generally think of MySQL, which, if memory serves, was started by people with little database knowledge, as not being as high quality as Postgres, which came directly out of another relational database project.
Statically typed languages are much more likely to be self documenting, though occasionally, with Golang for example, they will return a structure with the same name as another structure in the program, and it's hard to figure out which of these is being returned.
http://www.ieee.org/about/ieee_code_of_conduct.pdf
ACM Code of Ethics and Professional Conduct:
https://www.acm.org/about-acm/acm-code-of-ethics-and-profess...
cybertechnology?
https://github.com/id-Software/Quake
http://fabiensanglard.net/quake2/quake2_software_renderer.ph...
https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overv...
Not to sound pedantic, but did you mean "While you're at it:"?
The later book is "Artificial Intelligence A Modern Approach" which is written with pseudocode examples. The site includes other languages than lisp; python, java, js, scala, and c#.
PAIP lisp code: http://www.norvig.com/paip/README.html
AIAMA code: https://github.com/aimacode
http://fabiensanglard.net/
Reading this code is probably most enlightening if you have already written networking protocols.
NB: this has nothing to do with OCaml, other comparable languages with ADTs (Scala, Rust, Haskell, F#) would be similarly suitable.
[1] https://github.com/mirage/mirage-tcpip
[2] https://github.com/mirage/mirage-tcpip/blob/master/lib/tcp/s...
I've been looking for something beyond basic tutorial apps to get a real feel for OCaml.
Don't know OCaml but am learning Rust and I see what you mean about the universality of how types make this possible.
Thanks for pointing this out.
http://www.gigamonkeys.com/code-reading/
We should read source code sometimes (maybe) to deepen an understanding of how someone might think about the problem differently. In the link, Donald Knuth says he enjoyed the challenge of exploring a piece of software that had no documentation in order to figure it out.
In light of this, my answer to "what code should people read" is that you should read (really, decode) the source code of libraries competing to solve the same problem. This would lead to the greatest yield in terms of uncovering core shared concepts and core unique concepts.
You could compare Vue and React to understand how two different parties thought about componentizing the front-end. Or you could compare Django and Flask to see how a batteries-included MVC framework compares to a lighter alternative.
Typically if I don't know how to solve a problem / use a library, I'll go onto github and search out projects either by their dependencies or structures I know must be present in the code I want. Then I'll pick out 20-30 projects and compare and contrast. Funnily enough, I read most all of the source code to Etsy's 'Artsy' iPhone app because I wanted to get a sense of how a professional shop structured their iPhone code.
As for the understanding the code, the author is very correct in that it's tough to implicitly understand what's happening in the code. But to that point I use Reveal to peek inside iPhone apps, or node-nightly + chrome devtools to walk through js code. Since my goal isn't to understand the whole of a program, rather parts I'm interested in, it's worked out quite well.
I've always wanted to read code for very secure applications (like Signal or SecureDrop), but I fear I don't understand crypto/infosec enough to understand the context the code was written in.
In that regard Donald Knuth's work in the fictional assembler MIX for TAOCP is worth reading - it's at one remove from any real system. Knuth's TeX source is also quite unique.
Realistically this is because it is in fact a big messy pile of 'at least it works'.
Still, it is worth studying as an example of a work that was architected to support open source contribution from thousands of developers.
I have contributed to device drivers a few times, for example. And I wouldn't really recommend this part of Linux for learning. Maybe they work but code readability is often neglected and it's not unusual to see whole functions without a single line of comment or files/modules without even a short explanation of what they are trying to achieve.
Maybe the core is better.