This comes up often in Hacker News discussions, though usually without the qualifier I've quoted above, which I appreciate you adding. It's really easy to underestimate how much there is beneath the surface of almost any product.
People start by looking at Khan Academy and thinking "it's just a collection of videos, and even those are hosted on YouTube." But we've also got exercises and articles. Mostly created in-house, in a CMS that can handle the needs of creating math and science content. Translated into dozens of languages mostly by volunteers. Organized into courses based on, in some cases, regional curriculum.
We need to keep track of which content a learner has worked with and which skills they've mastered so that we can help them keep improving.
We connect with The College Board to help with specific SAT prep based on test results you've had.
Accounts can be logged into using Clever, which is common in school districts. They can be connected to Google Classroom, and teachers can assign content (and manage classes on the site).
We offer higher-level reporting for school districts, plus special tooling to get all of the district's students loaded into Khan Academy.
Around all of these features are the inevitable tricky edges. All of this needs to be able to handle millions of users every month.
In the process of doing this port, we _are_ actually deprecating some old and outdated stuff. Our site is 10+ years old. But most of what we have are features used by lots of people all the time.
Another thing is to be careful about deprecation and feature roadmapping that's developer-whim-/assumption-led instead of customer-led. It's too easy to say "nobody uses this" or "it's not important because nobody uses it" when it can be vital to certain users.
(600 moons ago, I took the SAT-I without studying or prep: 800 math. English... let's not go there.)
When we deprecate user-facing functionality, that's done with our product managers making the call, and involves usage data and a lot of coordination with our user support people. It's always a tough call, because someone out there won't be happy, but we have to choose the best path forward we can see at every given moment.
I'm not a big fan of LOC as a metric. You certainly can't compare languages. But the point that this is a large app and the builders are happy with their product and choice says a lot.
YMMV
khanacademy.start()
Just 1 LoC! =) if err != nil {
return err
}I threw in the towel and went to Rust.
I should be focusing on a high-level description of the problem, and the compiler should be filling in as much of the solution as it possibly can. My brain is made of meat and will never get any faster, so this is the only way for the profession to progress.
I disagree, it’s purely a count of newline characters per my original point (e.g., a third of the lines are just `}` or `]`).
> My issue with boilerplate is that we have lots of tools for generating it but no well-supported way to summarize it back to something human-readable
In my experience, it’s pretty easy to understand `if err != nil { return err }` and the like at a glance. Similarly a for loop that maps a `[]T` to a `[]U`.
I also dispute whether a long chain of .map().foldr().etc() is intrinsically more intuitive than a for loop, especially when the code needs to short circuit. Don’t get me wrong, I like using Rust-style iterator combinators in my hobby time, but it’s because they make me feel clever not because they are more readable than Go-style for loops.
TL;DR, I agree that our brains aren’t getting faster and that readability is important, I just don’t think newlines or the lackthereof are the measure of readability.
It's not simply that. Compare in golang:
var res int
if <some condition> {
res = foo()
} else {
res = bar()
}
to what other languages offer like let res = if <some condition> { foo() } else { bar() };
The golang version is both more verbose, and more error prone.These things add up. Let alone how it takes dozens of lines of code in golang to implement what essentially is a sequence of map/filter/groupBy. The logic in languages that support the latter immediately stands out, whereas in golang you have to read it line by line to figure out what's going on.
What's ironic is that even with the proposal to add some of those to golang, they're still going to be vastly inferior to the implementations we have in Java/C#/Scala/etc. because they don't compose in golang, and are still going to be very awkward to read.
The other way for the profession to progress is to eliminate humans (mostly) with self-programming machines (effectively, a technological singularity).