Ask HN: What are the “best” codebases that you've encountered?

392 points by 0mbre ↗ HN
I am rather fond of the concepts described in "Clean Code" by Robert Martin but it seems that in real life, a really high-quality codebase is hard to come by.

While I am asking myself this question, the only one that popups to my mind would be Laravel: https://github.com/laravel/laravel (PHP)

One could think that a codebase as popular as React (https://github.com/facebook/react) would be a perfect example of "clean code" but with a glance, I personally don't find it very expressive.

This may all be very subjective but I would love to see examples of codebases that member of this community have enjoyed working with

277 comments

[ 2.6 ms ] story [ 198 ms ] thread
Qt's codebase is very clean
I love Qt, and Qt has a great cross platform API. However Qt uses a lot of Qt-Only idioms, in particular there is has simplified memory management based on parent/child relationships (all children are deleted with parents), and also "COW" copy on write containers that can simplify programming but make it harder to reason about memory allocation.

Further, all internal classes also include a PIMPL (d-pointer or data pointer) to hide internal details from API customers.

IMO, The d-pointer makes stuff much more difficult to read, and the Qt idioms are probably only useful if you are a Qt developer. So maybe might not be useful for you if you are on a non-Qt project.

I thought QT was a collection of libraries, even with different licenses. As such, it seems strange to apply a word like "clean" to the whole thing.
Qt core and most libraries are written by the same group of people in the same development process.

Splitting it up into libraries is good engineering practice as it ensures boundaries. (Whether it is packaged into their own dll/so/a/dynlib is a deployment question, you can compile all parts statically together)

The licensing is a political/business question independent from code being nice, good and clean. (Except one has to be careful during refactorings, as code might change license, but since afaik the Qt Company has CLAs ensuring copyright ownership they are able to do that)

Recently had to make a few changes to ffmpeg codebase. It's pretty good.
The build system and assembly system (x86asm) are very underrated. Open source went from autotools, which are awful, to cmake, which also seems to be awful. ffmpeg's configure/make system has the same interface as autotools but is actually good.

libavformat is rather difficult to use and difficult to fix bugs in - you'll never find the bugs. Same with the ffmpeg frontend, which makes it easy to ask for something it's near impossible to get right, like copying an mkv file to an avi, it'll just corrupt your data silently.

Everything about the video decoders is great, but encoding never worked as well, which is why nobody uses ffmpeg2/4/etc and x264 is a separate project.

libavformat is rather difficult to use and difficult to fix bugs in - you'll never find the bugs.

Some examples?

encoding never worked as well, which is why nobody uses ffmpeg2/4/etc and x264 is a separate project.

Most users use x264 _via_ ffmpeg since they may need to filter the video and/or filter/process/mux audio and other streams.

> Some examples?

Just try copying video between different containers (mkv, ts, avi for one) without reencoding.

> Most users use x264 _via_ ffmpeg since they may need to filter the video and/or filter/process/mux audio and other streams.

They don't have to do that; you can handle each track separately and mux them back afterward.

I'm talking about ffmpeg's builtin MPEG2/4/MP3 encoders, which nobody used when they were competitive because it leaves all the options at "go fast" instead of providing tunings.

They're also unmaintained and the code is hard to figure out - that's why x264 was a separate project instead of just another part of libavcodec.

Just try copying video between different containers (mkv, ts, avi for one) without reencoding.

I do, all the time. AVI is an old container and it has issues with B-frames and also VFR but those are container limitations, not a libavformat issue. All transmuxing between common modern containers with present-day common codecs work fine. There are always edge cases, but that's what they are, edge cases.

you can handle each track separately and mux them back afterward.

Why do that? What's the benefit?

I'm talking about ffmpeg's builtin MPEG2/4/MP3 encoders

You seem to be talking about the state more than a decade back. How's that relevant to 2019? BTW, there is no native MP3 encoder.

I know it's a cliche but the sqlite code is the easiest to read C I've encountered. Followed closely by the code for Redis.
I also like the C source for Tcl/Tk which I think also follows similar engineering/style standards.
The author of Tcl/Tk wrote a fantastic book recently called "A Philosophy of Software Design" and it's brilliant, hands down my favourite programming book of the last decade.
Tcl/Tk is listed below by others, but it’s worth noting that both Richard Hipp (SQLite) and Antirez (redis) are (or were) very deeply involved with Tcl. I think there maybe a positive feedback loop/environment wrt engineering discipline. It’s worth exploring. I also second the praise below of John Ousterhout’s (inventor of Tcl/Tk) book “A Philosophy of Software Design”.
What do you like about Laravel and dislike about React?

I like the Linux kernel codebase: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...

> I like the Linux kernel codebase

Same here, I was looking at linux kernel network code lately and I was surprised by how clean and easy to follow it was.

At some point in Martins book, he mentioned a forgotten codebase from one of his friend that was solely composed of tiny functions but yet achieve a fairly complex effect. That's the kind of feeling I had working at Laravel (admittedly it's been a few years). React codebase, on the other hand, seem less human-friendly, it seems to require some prior knowledge of the code to be able to dive into.
I'm really curious how you see laravel as a shining example of clean code?

That thing is the epitome of a framework for frameworks sake.

Pretty sure Most of Martin's talks begin by complaining about this sort of thing?

> That thing is the epitome of a framework for frameworks sake.

Go on

Any PHP framework is a case of inner-platform: https://en.wikipedia.org/wiki/Inner-platform_effect

PHP already is the "framework" and every time you load a page it's executing the script from scratch. You're wasting a lot of time loading a framework to handle control flow for your program which doesn't have any control flow in the first place.

I'm not a PHP dev, but I've dabbled. And I'm not sure I follow. How is it a framework for frameworks sake? I take that to mean it's pointless/not useful. Whereas I'd say Laravel and it's ecosystem are far more productive and time saving than simply using just PHP. It's the opposite of wasting time. From their github repo[0] Laravel has:

- Simple, fast routing engine.

- Powerful dependency injection container.

- Multiple back-ends for session and cache storage.

- Expressive, intuitive database ORM.

- Database agnostic schema migrations.

- Robust background job processing.

- Real-time event broadcasting.

Not only is it a robust, pleasant, framework with batteries included but there's also an entire ecosystem/platform of related products that are pretty big time savers:

spark[1], forge[2], envoyer[3], and horizon[4].

And, as an aside, the documentation is good and there are some pretty great tutorials too[5]

What am I missing?

[0] https://github.com/laravel/laravel

[1] https://forge.laravel.com/

[2] https://spark.laravel.com/

[3] https://envoyer.io/

[4] https://horizon.laravel.com

[5] https://laracasts.com/

These features don't make sense for PHP's execution model, your script is supposed to render one page and then exit. There's nowhere to put background tasks, event handlers, etc. Is it doing something else? I can't imagine turning PHP into an application server, and if you were, I'd suggest getting a different language.

It's possible to have request routing if you want to have the same .php file serve every request on your site, but that's totally inner-platform. There's already a thing routing URLs and it's the web server.

I'm not fully on board with all of Roberts views but this point about a framework for frameworks sake is one I agree with.

https://youtu.be/o_TH-Y78tt4 starting at around 10:30 he gets into what I was getting at.

> Whereas I'd say Laravel and it's ecosystem are far more productive and time saving than simply using just PHP.

I'm not arguing a time thing.

I'm arguing that a framework that forces its architecture onto your domain model is fundamentally broken by design. My domain should drive architecture choices and the framework should let me augment that with well worn libraries and modular patterns.

Laravels architecture works for one thing: web sites. And for that, you're better off using WordPress.

Laravel is better than older frameworks, like say, code igniter but it still fights you every step of the way if you want to step outside the box.

> Laravels architecture works for one thing: web sites.

From the github repo:

“Laravel is a web application framework with expressive, elegant syntax”

Web applications are not websites.
I want to understand your points more clearly.

> Laravels architecture works for one thing: web sites. And for that, you're better off using WordPress.

> Laravel is better than older frameworks, like say, code igniter but it still fights you every step of the way if you want to step outside the box.

Can you provide actual examples of where it "fights you every step of the way"?

> Web applications are not websites.

So can I infer that a building a web application with Laravel would be stepping "outside the box"?

If so, could you please give examples of how building a web application with Laravel "fights you every step of the way"?

A software's usefulness is not correlated to how well it was architected. What I like about Laravel is that its fairly complex code base that is mostly composed of tiny and expressive functions
I'm not sure I follow.

We're not talking usefulness here we are talking about clean code.

Architecture is not only correlated but causal in this situation.

It's over architecture is the problem. It's nano functions are a positive side effect but don't change the indirection problems you face.

Anything by John Carmack. (DOOM's open source release, for example)
I think the best codebases are the ones you immediately think “Oh, that’s easy. I can reimplement that in a couple of hours.”. When it's not. It’s never easy.
For a C codebase, Postgres[1] wins for me hands down. It's clean and suuuuuuper well commente, such that with a little context you can dive into something very complex and still get a feel for what is going on.

[1]: https://github.com/postgres/postgres

Second this; Postgres codebase is what got me out of the "good code is self documenting" nonsense. For those of us in the database space it is an incredible resource - and overall a great example of good code.

sqlite is much less complex, but similarly approachable.

In more recent examples, I think you see a lot of this same reader-centric pragmatic ethos in many Go projects. The Kubernetes codebase comes to mind as a very large tome that remains approachable. And the Go stdlib, of course.

Java generally falls on the opposite side, but there are counterexamples. A lot of Martin Thompsons code eschews Java "best practices" in favor of good code. Seeing competent people in the Java space "break the rules" helps.. though of course Java is forever hampered by having internalized illegible patterns as best practices in the first place.

It's a shame because at least the OpenJDK implementation of the standard library in Java is generally quite good, especially around the concurrency parts. Clean, easy to follow, reasonable comments. But of course that's Java written by C developers, mostly.

/* don't even try to load if not enabled */ if (!jit_enabled) return false;

I still think comments like these are super redundant and annoying.

Agreed, sounds like trying to convince that imperative code is an easy reading. But OK, for some people it may be.
It tells you the intent. The actual code does exactly that, because the intent matches the code, but sometimes the two aren't aligned and therefore the "redundant" comment can help you determine if the bug is the code or the intent.

Understanding the "Why?" of code is often the most valuable thing about comments. The code remains forever, but the "Why?" is often lost to time.

Except that it does not. The 'why' would be explaining why the jit needs to be enabled to be able to load. As it stands it explains the 'what' and therefore is a bad comment.
A point well made. I conceded it could have been better written.

I still believe "redundant" comments can be of value though. This just may not be the best example.

> It tells you the intent.

A good unit test that tries to load with jit_enable=false and expects false in return will communicate intent even better.

Comments are usually less prone to logic bugs. When fixing issues, if the code behaves opposite to what the comment says, it can be a very helpful clue.
An argument can be made that this is what Test Driven Development is here to solve. State intent in the test, not the comment.

That said, I agree it can be a helpful contextual clue.

Heh, that's one of mine. The point isn't so much to restate the if itself, it's to explain that we're explicitly testing before loading the JIT provider - which happens immediately below.

Which in turn is because we a) do not want a hard dependency on any JIT provider, in particular we don't want a hard dependency on LLVM b) LLVM is a really slow to load dependency. Those bits are expanded more upon in the README in the same directory.

Edit: expand.

I think that beauty of OpenJDK concurrency mostly seems to come down to Doug Lea being a genius of concurrency.
>the "good code is self documenting" nonsense

Man I hate dogma like that. My "common sense" comment style is always, "code tells me how, comments tell me why." The only exception is in hand optimized code where I'll non-doc comment what the reference implementation would be above the optimized version, which is _sometimes_ necessary when tests aren't in the same translation unit.

Totally agree. It is impossible to show why one tradeoff was chosen over another without comments. Is there a loop unrolled for performance reasons? Is there a design goal that looks complex on the inside, but yields a simple, easy to understand API on the outside? I feel like "good code is self documenting" is a pitfall that devs always fall into believing on their journey to becoming a "Senior", and then somewhere along the way run into their old "good" code and can understand what it does perfectly well enough, but cant recall the circumstances that led them to arrive at the choices they made in writing that code.
Comments tell me why if I happen to be asking the question the comment is answering. You can't answer every "why" question in a comment. If you take "good code is self documenting" as dogma and say, "therefore I won't write comments", then probably you deserve what you get in the end ;-) But good code reduces the number of questions I might try to ask. That way I can get down to one "why" or possibly even no "why"s.

For example, I can write "a - 1" or I can write "-1 + a". If I write the second form people are going to wonder why I did it that way. Is there some reason why "a - 1" wouldn't work? Perhaps I don't have a - operator for a for some reason. But if I have no reason to write it the second way, then I should avoid doing it because then I don't have to write a comment saying, "I did it this way for no reason".

That's a simple and contrived example, but it holds true for larger code as well. There are ways of doing things that follow the programming culture most of us share. We shouldn't comment everything we do -- only the things that are unusual. Otherwise we'll be lost in comments. I'd rather read code to understand what's going on than English if I can help it.

So, the lack of need to write comments can indicate a good code base. However, like many things, it's a poor metric. The lack of comments does not indicate a good code base ;-) Similarly, some things are just complex, or unusual even when you have simplified it as much as humanly possible. Generally speaking, though, if you have a choice between code that needs a comment and code that doesn't need a comment, choose the latter.

> Postgres codebase is what got me out of the "good code is self documenting" nonsense.

I'm a fervent believer in "good code is self-documenting", so I was curious to be proven wrong, clicked randomly until I found code and I saw this.

    /*
     * Round off to MAX_TIMESTAMP_PRECISION decimal places.
     * Note: this is also used for rounding off intervals.
     */
    #define TS_PREC_INV 1000000.0
    #define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
Usage of acronyms is one of the worst offenders in bad code. The context makes it clear that TS means timestamp, so that's not too bad (still bad though), but I'm still not sure what INV means, luckily I presume it's the only place it's used.

If it was named TIMESTAMP_ROUND, I wouldn't need to know "Round off to MAX_TIMESTAMP_PRECISION decimal places." Now that I've copy/paste that, it seems like the comment is wrong too, it's rounded off based on TS_PREC_INV, so if I was to believe the comment, I wouldn't get the right behaviour.

I'm not saying Postgres codebase isn't good code, just that "good code is self-documenting" is still true. That code was pretty much self-documenting except for the acronyms, but considering it was all used together, it's was fine and I was able to understand what they meant.

For me, comments should only be needed when something isn't clear. Defining what isn't clear is hard to determine for sure, but that's one thing for which code review helps quite a bit.

> If it was named TIMESTAMP_ROUND, I wouldn't need to know "Round off to MAX_TIMESTAMP_PRECISION decimal places."

With only the name, how would you know how many decimal places? The comment isn't wrong/out of date here btw.

> With only the name, how would you know how many decimal places

I'm not saying the name is wrong because of the comment, I'm saying it's wrong because of the usage of the acronym.

> The comment isn't wrong/out of date here btw.

Isn't wrong? How? It's true in the sense that they expect TS_PREC_INV to be related to MAX_TIMESTAMP_PRECISION (which would be a perfect example to my mind of a needed comment, if actually it was a requirement), but it's actually false in the sense that it's not what that code does.

You wouldn't get a different rounding if you were to modify MAX_TIMESTAMP_PRECISION, which is what you would expect based on that comment.

> I'm not saying the name is wrong because of the comment, I'm saying it's wrong because of the usage of the acronym.

I get that. But you also said the comment would be unnecessary with a name change. The comment does communicate more information than your proposed name, IMO, hence is not replaceable by the name. (IMO).

> You wouldn't get a different rounding if you were to modify MAX_TIMESTAMP_PRECISION, which is what you would expect based on that comment.

Good point. The comment isn't wrong with the definition of MAX_TIMESTAMP_PRECISION as it is in the code. If you override it though, the code doesn't do what the comment says.

It's an interesting case: if you trust the comment indicates the desired behavior, then you can see the code may have room to be improved. If you distrust that the comment is correct or has value, then you might just remove the comment, and the code doesn't get better.

I mostly agree with this. Though as I wrote that sentence I realized Go has somewhat softened my position on abbreviations. I think the "note" portion is useful; ultimately a test would stop you breaking that secondary use, but the comment stops you spending time in that direction in the first place. But either way, overall I think you're right this would be fine without a comment.

I'm thinking more of examples like this: https://github.com/postgres/postgres/blob/master/src/backend...

I just picked this at random from the storage subsystem, but I think it highlights what I mean. The comments are mostly about context. The comment for the routine is about when and who calls it, so that someone that reads the routine has that in mind. The specific line I'm linking to highlights in English prose that the correctness checking on the page headers is just a minimum guard and should not be fully trusted.

Back in the day I would have argued "oh, well, but you could break that into a function called "provisional_page_header_check(..)", or something. But.. there is nothing in the compiler that checks that function names stay in sync with their implementation any more than there is for comments. Writing it as a comment lets you use regular English sentences, breaking out a function takes that away and adds no compiler protection.

It's also.. friendly, somehow, to me. Working in this codebase is like participating in an ongoing and very slow conversation, which feels very pleasant.

That comment is exactly what I mean by when needed.

That does confirm that they are making pretty amazing code. I would have much prefered to get that file instead of the other one :P.

They do have a redundant comment at someplace but it's clearly a tiny minority and they aren't losing any one time.

Yep, I think we're in agreement :)
>If it was named TIMESTAMP_ROUND, I wouldn't need to know "Round off to MAX_TIMESTAMP_PRECISION decimal places."

TSROUND is already as obvious as TIMESTAMP_ROUND. TS is a very common abbreviation of timestamp.

And you would still need to know the decimal places.

The real issue is that it's based on TS_PREC_INV and not MAX_TIMESTAMP_PRECISION as per the comment (though MAX_TIMESTAMP_PRECISION might still agree with the decimals offered by TS_PREC_INV, it's not obvious here, and would need manual work to keep them in sync).

> TS is a very common abbreviation of timestamp.

Common != universal. It's known up until someone doesn't know it. We have pretty powerful autocompletes, let use them instead, or just lose 3 seconds writing the 10 letters, it won't be so bad.

> And you would still need to know the decimal places.

Sure, by reading the code and understanding what it does and how it does it. You change a constant that will affect that code, it seems fine to see how it's affected either way.

> The real issue is that it's based on TS_PREC_INV and not MAX_TIMESTAMP_PRECISION as per the comment

Which is bound to happen when your documentation isn't the code directly.

> > TS is a very common abbreviation of timestamp.

> Common != universal. It's known up until someone doesn't know it. We have pretty powerful autocompletes, let use them instead, or just lose 3 seconds writing the 10 letters, it won't be so bad.

The cost of that compounds though. There's plenty times where there is not just one abbreviation in a symbol name, but multiples. And pretty soon the "logical" lines long enough to contain multiple references to such symbols get considerably slower to read (be it due to long lines, or being broken up into multiple lines).

I've an extremely hard time to believe that the widespread use of ts, xact, wal, ... is a significant factor in how quickly somebody can get started with the postgres code base.

> > The real issue is that it's based on TS_PREC_INV and not MAX_TIMESTAMP_PRECISION as per the comment

> Which is bound to happen when your documentation isn't the code directly.

Hm? Those aren't out of sync? TS_PREV_INC is the relevant factor/divisor to round to MAX_TIMESTAMP_PRECISION here. It'd be nicer if that were explicit in the code by defining TS_PREV_INC based on MAX_TIMESTAMP_PRECISION, sure, but they're in sync. It's just not that trivial to state in C. But they're in sync. Note also that TS_PREC_INV really is just an implementation detail for TSROUND(), it's not used elsewhere. These days we'd just write this in an static inline function, in all likelihood.

>Common != universal. It's known up until someone doesn't know it.

Someone might also not know what a timestamp is, or a UNIX timestamp at least, so there's that.

>We have pretty powerful autocompletes, let use them instead, or just lose 3 seconds writing the 10 letters, it won't be so bad.

The problem with the above idea is that it implies "spelling it out fully == better". Which is not necessarily the case, long variable names can make code hard to follow and verbose. Ask the Java community...

IMO good code needs to be readable at the call site much more than the function definition. That’s why I believe in the Google C/Go style rule that all mutable parameters must be passed by pointer. A call site with &arg communicates mutability quickly. Also, in my framework designs I consider the impact on code complete heavily:

E.g. in the above sample “TS” is commented to mean timestamp but that will be lost during scans of code complete options. Also, MAX_TIMESTAMP_PRECISION may not show up in code-complete for timestamp macros/consts, but TIMESTAMP_MAX_PRECISION will.

Are there guidelines for when abbreviations are ok in Python code? I tend to avoid them except popular abbreviations like admin and ts.
It's like in any sizable codebase with quite some history. There's substantial difference in quality between parts. Some of the worst parts go back to the early days of postgres - the priorities and resources available back then were just very different than today. Obviously there's also noticeable differences in more recent code, but I don't think to the same degree (although there've been definitely subsystems that worked out better and some that worked out worse).

E.g. the code above is essentially (although somewhat mechanically renamed and moved since), from:

   commit 41f1f5b76ad8e177a2b19116cbf41384f93f3851
   Author: Thomas G. Lockhart <lockhart@fourpalms.org>
   Date:   2000-02-16 17:26:26 +0000

       Implement "date/time grand unification".

> Usage of acronyms is one of the worst offenders in bad code.

Not really on board with that... It's a balance. Brevity does have it's value too. Everybody is going to understand that TS stands for timestamp, that WAL stands for write ahead log, etc. Especially when dealing with a language that doesn't have namespaces etc, you're going to have to realistically deal with prefixes a good bit. There's plenty of bad abbreviations in postgres code, however, don't get me wrong.

In the above I'm more bothered by the inconsistent naming, which I think is probably one postgres' bigger code quality issues.

> For me, comments should only be needed when something isn't clear.

I pretty strongly disagree. Most of the time comments shouldn't explicitly restate all that code is doing, sure (although there's clearly exceptions to that too). But e.g. stating why an algorithm is doing something, what the higher level goals of some checks are, why some shortcut is reasonable all make a code base a lot more maintainable in the medium to long run.

I work a lot on postres, and occasionally dabble around the corners of linux. For me it's the* defining difference making it much more painful to understand most linux subsystems.

Edit: formatting, typo

> For me, comments should only be needed when something isn't clear. Defining what isn't clear is hard to determine for sure, but that's one thing for which code review helps quite a bit.

Totally agree. Comments should be limited to sections in which the code is unexpected. For example, for a workaround for a bug in another part of the system. That you should comment because if the bug is ever fixed someone reading the code will understand why it looks wonky.

I don't agree with acronyms. They are fine to use as long as you are consistent. For example, if you write "ts" in one place, you can't write "timestamp", "tstamp", "tstmp" for the same data in some other code. In my code, I always use "n" for "length". Since I'm consistent about it, and ever use "n" for anything else, it doesn't make the code harder to read.

(comment deleted)
Back when I maintained postgresql on cygwin I did it because if its clean codebase. But eventually I got struck when trying to fix a build system bug when creating importlibs. On all other build systems it was easy to fix the bug, but no so with postgresql. I eventually gave up after years, and I think it's still broken.

A special mingw tool to create importlibs is/was broken on 64bit. I think it was called dlltool. Normally you'll just need to add a flag to the linker to create that.

So no, postgresql not.

The Codemirror codebase [0] is simply written and richly commented, and using Codemirror itself in a project is a pleasure.

Tellingly, Marijn Haverbeke, Codemirror's creator, is also the author of the excellent 'Eloquent Javascript' [1].

[0] https://github.com/codemirror/codemirror

[1] http://eloquentjavascript.net/

It's unfortunate that the author doesn't appear to understand the value of a strict Content-Security-Policy.
many mature frameworks have good standards. For php you can look at any code base that adbides by PSR standards and get good code.

Not only that but laravel is in a mature space where the problems are already solved. Its basically reinventing the wheel.

Im not surprised that Laravel is written cleanly but I hate its API. It reminds me of the bloat of Zend but with an obnoxious artsy style added to it.

Im an engineer not an artisan.

> Im an engineer not an artisan.

That was mostly branding, "I'm not a code monkey banging out the same thing as has been done 500 times before I'm an artisan.

Meanwhile the actual framework breaks backwards compatibility regularly and frequently and only just with 6 picked a damn versioning system.

Imo my opinion if you want to see a good framework that solves it's problems mostly well and is properly decoupled then Symfony kicks the shit out of Laravel on documentation, religious adherence to deprecating and backwards compatibility as well as genuinely useful/genuinely decoupled components.

The author of Laravel knew that as a massive chunk of Laravel depends on Symfony components, in fact the earlier versions where basically Ruby on Rails implemented via Symfony.

> look at any code base that adbides by PSR standards and get good code.

No. PSR does not at all ensure good code, only standardized code style and some of the interfaces.

PSR is an abomination. You end-up with more blank lines than code and about 5 lines of doc comments to every line of code. Factor-in PHP's pseudo-Java verbosity and the actual business logic is drowning in a sea of boilerplate.
It does one thing: It indicates the author is willing to use "established patterns" instead of reinventing the wheel. (While sometimes it's good to reinvent the wheel - today's vehicles won't work with wodden wheels)
Kubernetes for Golang. This has been brought up as an example of fine documentation: https://github.com/kubernetes/kubernetes/blob/ec2e767e593953...

Requests for Python https://github.com/psf/requests

I’m not sure I’d call Space Shuttle Style appropriate for 99% of code, but it does make it easy to read and harder to mess up down the road.
Space Shuttle Style is appropriate when the design is fixed, the code is extremely tricky and it's very difficult to test - in other words, when it's not possible to follow normal good coding practices.

If you can comprehensively test, then the docs can live there, and you don't need quite so many warnings about introducing bugs.

K8S was transpiled from Java, and it shows. Much of the code isn't idiomatic Go at all. So I wouldn't cite K8S as a shining example.

Comments like the one cited are fantastic, but we're interested in examplars of good (i.e., elegant and readable) code, not ancillary matter.

Unreal 4 is far from perfect but considering the size of the project I would say its pretty impressive.
I really liked the Go standard library (or at least from around 1.4-ish, it might have gotten more complicated now).

I liked that it was actually possible to read it and understand what was going on.

In a similar vein, P. J. Plauger's version of the The Standard C Library is nice because even if it might not be especially optimized(?), you can actually read the code and understand the concepts that the standard library is based on.

Software Tools by Kernighan and Plauger would also be great except that you have to translate from the RatFor dialect of Fortran or Pascal to use the code examples.

Even so, I used its implementation of Ed, to create a partial clone in PowerShell that let me do remote file editing on Windows via Powershell when that was the only access that was available.

So even over 4 decades and various operating systems removed, there are still concepts in there that are useful.

Jonesforth is also a great and mind blowing code base although I'm not sure where the canonical repository is currently.

I wish there was a way to read the codebase where there is a tag that tells you what the folder does.

In github, rather than see what has changed, it would be interesting if there was a comment that told you what the folder contained.

edit: Relevant here because the best codebase for me is one where I can understand the folder structure, but that is a sort of 0th order effect that should be equalized with some tool.

Java did this with package-info.java. It is underused, in my experience.
In Go, a folder is a package and as soon as you write a comment before the `package foo` declaration, it's package documentation. And thus GoDoc automatically generates a nice webpage out of it.

See for example this package comment: https://github.com/golang/go/blob/master/src/net/http/doc.go...

Turns into this documentation (the beginning only): https://godoc.org/net/http

Out of the box.

Nice. I like the way it also shows you the functions inside a file/folder, and that clickable index is nice.
What's the point of all these empty comments throughout the code?

    // ...
It's likely the Go libter requiring every public method / variable to be documented.
Yup. I saw a lot of codebases with things like:

// EnqueueEvent ...

func (q *Queue)EnqueueEvent(event Event)

It's just an ellipsis indicating that there be would more code after.
It sounds like you're describing a Readme file -- which by convention can exist as documentation for any folder and not just the project root. It's not adopted by all codebases but is becoming more common as source browsers like Github will render the readme as rich text when navigating to the folder.
readme files might be the natural place for them but in practice readme files sort of tell you about the project, the author, the purpose, examples of what it can do and maybe how to install it.

It rarely gives you what is in each folder, and what part of the functionality each folder handles, although perhaps we should try to change the conventions of readme files to include file structure.

edit: I mean the root readme might contain what is in each folder so you don't have to click on each one to see which one you want to start with.

Yep. For some of the larger projects that I've worked on, I've gotten into the habit of adding folder level READMEs. I don't know if anyone else has benefited from them, but I certainly have myself when I need to remind myself of some context or pitfalls.

Having a sensible folder structure and good folder names is nice, but taking a few minutes to write individual READMEs can make a repo even easier to understand.

Well, Symfony's codebase is really great: It is very readable, It's behavior is logical, The documentation is great, It uses common patterns (solid), so you are never loss
NetBSD, hands down. Beautiful, simple to understand, consistent. The documentation is also top notch -- I wrote a trivial character-device kernel driver using only the man pages as a reference. And you can too.

Also -- the source code to Doom. Read it, marvel at its clarity and efficiency -- and then laugh when you realize that the recent console ports were completely rewritten in fucking Unity. And the Switch version chugs, despite the original running well on 486-class hardware.

I completely agree. I've gotten to work with both of these at my summer job and it's been an absolute pleasure.
You've gotten to work with both NetBSD and Doom in one summer job? Now I'm really curious what you've been doing. I think I may want that too.
(comment deleted)
Think about it. When you stand up a new ARM-processor embedded widget for the first time, what are two of the first things you do to verify it works?

1) Port NetBSD to it

2) Port Doom to it

My project was to port DOOM to the seL4 microkernel (on rpi3b+). To continue with that I’ve been porting NetBSD Rump kernel components to seL4 as well.

DOOM itself is a breeze to port. NetBSD can get confusing at times but it’s nice to know there’s always a logical reason behind the design decisions. It rewards you for spending time to understand the code and I like that. Rump kernels are especially cool.

It’s a myth that you can’t get paid to work on BSD ;)

Unity sucks but as a hobbyist game developer it is a godsend. The only other way I can support all the platforms I want to (Android, web, PC) is through Web APIs directly, and nobody likes more Electron.
SDL be like "am I a joke to you?"
SDL is fine for cross platform development. Personally, I have used it for some commercial games in the past, but I think it's not comparable to Unity or unreal engine. SDL is not a game engine, it provides only lower level features (audio, opengl context initialization, joystick support, etc). Even for things like in-game menus and text rasterisation you are on your own.
Well there is also Unreal Engine!
> and then laugh when you realize that the recent console ports were completely rewritten in fucking Unity. And the Switch version chugs, despite the original running well on 486-class hardware.

I wonder why they didn't just write an emulator, then. Especially on the Switch if there are performance issues.

I used NetBSD as a reference when I needed a cross platform strptime that behaved identical everywhere.

I found the source very approachable. Source was well laid out and fairly clear. Some of it was subjectively a bit ugly to just look at, but when you read it, it was very clear.

Couldn't use glibc as a reference because this in a closed source commercial product and, well, GPL.

Java: joda-time

C: redis

Python: scikit-learn

_______

Edit: formatting

For canonical C code, without a doubt I would say Redis and Postgres. Redis is written and annotated in a way that even someone with a cursory knowledge of C can understand what's going on.

For Python, I really like how SQLAlchemy is written and designed.

For Rust, ripgrep stands out as a sterling example of how to write a powerful low-level utility like that.

I just opened up server.c in Redis (not familiar with Redis and never seen it before) and at first glance it seems... alright, but I'm not sure what's particularly outstanding about it, and it could definitely be better. Some of the logic seems questionable (exit() in a signal handler? [9] also what about thread safety?), and more superficially (but annoyingly) I see: names like "sdscatprintf" [1] which are a little cryptic, lack of attention to spacing (too little [2] or too much [3] or inconsistent [4] [8]), lack of braces for single-line blocks (which at least I consider bad) [5], irritatingly inconsistent line breaks [6], etc.

Overall it's still definitely on the more readable side compared to other C code I've seen, I like the thorough comments, and it's generally decent, but I'm not particularly coming away from it in awe like everyone else seems to have.

[1] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[2] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[3] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[4] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[5] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[6] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[7] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[8] https://github.com/antirez/redis/blob/unstable/src/server.c#...

[9] https://github.com/antirez/redis/blob/unstable/src/server.c#...

sdscatprintf is just mimicking the C style for a lot of string manipulation functions that have -printf suffixed. My guess would be the function just concatenates the data onto some sort of "SDS" string
Redis code quality could be improved significantly, but you picked the wrong file to evaluate it: the first file created, and the one that for the nature of system software will be the less "overall designed", because it is the place where we call almost everything else sequentially. Still, if I had more time, I could improve it and other parts a lot. However to see how modern Redis was coded check the following:

* hyperloglog.c

* rax.c

* acl.c (unstable branch, the Github default)

* even cluster.c

Everything you'll pick will likely be a lot better than server.c

Other things you mentioned are a matter of taste. For instance things like:

    if (foo) bar();
Is my personal taste and I enforce it everywhere I can inside the Redis code, even modifying PRs received.

The line breaks are to stay under 80 cols. And so forth. A lot of the things you mentioned about the "style" are actually intentional. The weakness of server.c is in the overall design because it is the part of Redis that evolved by "summing" stuff into it in the course of 10 years, without ever getting a refactoring for some reason (it is one of the places where you usually don't have bugs or alike).

Ah I see. I didn't realize it was old, I just picked server.c since it just sounded like it'd have a decent mix of stuff. I think the only 'taste' things I mentioned is the lack of braces and possibly the function name, which I'm happy to ignore. But the rest were just inconsistencies, regardless of which way anyone's tastes lean -- the spaces after commas are entirely inconsistent (although I would argue if you took the stance that there shouldn't be a space at all, that's bordering on just being wrong, not merely a matter of taste!), and some lines are far longer than 80 columns [1] and some are broken at really inconvenient points just to fit them into 80 columns, which gets you the worst of both worlds.

Thankfully, like you said, the other files do seem better. :) However, they do have the same problems I just pointed out above: spaces are inconsistent everywhere (after commas, after 'while', after casts, etc.) and lacking in awful places (honestly, how am I supposed to read a function call with eight identifiers and zero spaces? [2]) and some lines are broken and others longer than 80 [3][4].

A couple other immediate issues I have on syntactic things (semantic analysis would take me a long time so it's hard to give me feedback on that):

- One comment I have that some others would vehemently disagree with me on is: I would cut down on the early returns. Personally, I really hate them, for multiple reasons -- the most practical one of which is that they prevent you from inserting a single breakpoint in a debugger (or printf(), or whatever you feel like doing) and being able to see what the function returns easily. Instead, you have to hunt through the entire function and place a dozen breakpoints to make sure you didn't miss any return path. And it becomes the most confusing thing in the world when you inevitably miss one. To me that's bad enough, but some people still insist on them. But if you're going to do that, I would at least make it easier for people to debug them. On my first reading, for example, I completely missed the return on line [5] -- because it's right after the if condition and visually blends in. That also makes it hard if not impossible to put a breakpoint on it, which wouldn't be an issue if it were on a separate line. (Maybe you don't do that because you don't want to forget braces, but you know my opinion on that too. :P) That makes it even more painful to debug this function.

- I'm not a fan of the liberal macro usage. I'm not saying you should never use macros -- I know that sometimes it's outright impossible not to (especially in C), and sometimes they're the perfect tool (code deduplication) -- but you shouldn't be using them to use them to define constants and perform normal function calls. [6] [7] Not only is it often possible to break them because of their textual nature, and not only do they lack type information that would be extremely useful, but they also make it harder to debug, since you can't just type them into a debugger at runtime and get their values. And you can't step through them like normal code either.

Hope some of this is helpful. All of it said though, they're pretty minor things overall, and the code does seem good quality, at least as far as I can tell in in this timespan. The fact that it's in C does always leave me with this nagging feeling that there's always going to be some resource leak somewhere (especially with early returns!), which I wouldn't have in most other languages, but that's not really an indictment of the code but of the language. And I love, love, love the comments. I don't leave comments nearly that good myself, and I will almost certainly refer back to them later.

[1] https://github...

> Redis is written and annotated in a way that even someone with a cursory knowledge of C can understand what's going on.

Strongly agree with this one about Redis.

Anything by burntsushi, but especially xsv and ripgrep:

xsv: https://github.com/BurntSushi/xsv

ripgrep: https://github.com/BurntSushi/ripgrep

His code typically has extensive tests, helpful comments, and logical structure. It was fun trying to imitate his style when writing a PR for xsv.

The Quake 2 engine was also pretty interesting: It was almost totally undocumented, and it had plenty of weird things going on. But I could count on the weird things being there for a reason, if only I thought about it long enough.

Note: this assumes you speak Rust...
Don't all the comments assume you speak the language the codebase is written in? I mean I can't tell if a given PHP/C/Perl/other language I don't know well codebase is good or not. I guess there could be people that can somehow do that...
Yes, but other comments actually mention the language, and the original post was using web languages as an example, so I thought I'd save someone the trouble of clicking expecting and realizing it's not what they expected.
Seconding burntsushi. I learnt the basic Rust idioms by doing the advent of code last year and comparing my solution to his.