Norris Numbers – Walls you hit in program size (2014)
teamten.com
teamten.com
To go beyond that you need a few tricks of the trade, mostly structured programming and avoiding global scope will get you to 10K and up.
After 50K or so you will need even more tricks: version control will become a must, naming conventions matter and you're probably well into modularization territory. Some actual high level documentation would also not be a bad idea.
By the time you hit 100's of thousands of lines you are probably looking at a life-time's worth of achievement by a single programmer, or more likely you are looking at teamwork. And so you'll need yet more infrastructure around your project to keep it afloat.
You can see quite a bit of this at work when you browse through open source repositories at github, those are roughly the points at which plenty of projects and up being abandoned, as often as not through lack of insight in how to organize a larger project as through the demotivation that comes from lack of adoption.
I do not see how 1K of C and Python lines are same.
Meanwhile, a couple of weeks ago, I had to add a new feature to firmware that was already using just under 900 of the total available 1024 bytes of program space.
In my embedded work I pushed a few years back to upgrade the microcontrollers we used from 2kB to 16kB RAM and 16kB to 128kB flash devices (at a grand total extra cost of $2) so I could stop worrying about how we would fit all the new features in.
My personal line for "embedded" at the point where you take responsibility for the OS functionality too. IMHO that's currently somewhere around Raspberry Pi etc devices, which on one level have computing power in line with the smartphone world, but on the other you're still mucking around with the OS yourself. I know it's pure snobbery on my behalf, but I still cringe to think about Node.js running on them... (even though I'm doing it myself for hobbyist level stuff).
Also incidentally, in my experience, good embedded programmers are less prone to "get lazy" on devices with sprawling amounts of resources than less experienced embedded programmers. Hungry dogs run faster, yes, but for example just because we've been given a generous 32KB of program space doesn't mean we're going to use it all up in a fit of laziness or start cramming in the features.
I'm saying this isn't true. APL is the extreme example, but languages vary quite a lot in how many constructs you can and do cram onto a single line.
Unfortunately many developers prefer to use a slightly different trick: find similarities between different chunks and extract them as common interfaces. It makes you feel smart, and sometimes even works well, but usually it leads to framework disease. Library style is simpler and scales better than framework style.
Sometimes I take more time to think of a proper and scalable name for variables and methods than the time it actually took to write the implementation. While refactoring I might do another round of thinking about naming and make sure there are no or an absolute minimum of possible side effects for the implementation, etc..
I'm coding almost 30 years now. I'm still learning and make my mistakes of course, but most of the time they occur because I rush for some reason. Writing good code takes time, especially to rethink what you're doing, refactoring, making the right adjustments so it completes the codebase. Before I complete the beta release of a codebase I've made thousands and thousands of decisions, where only 1 wrong decision can cause a terrible amount of trouble later on.
For me it's a creative process. It goes in waves. I cannot always be a top performer, I've accepted that. When I recognise I was in a low during some implementation I might do a total rewrite of it or apply some serious refactoring(and force myself to take the time for that).
I still experience coding to be much harder to get right than I ever expected it to be. For me a codebase is a highly complex system of maybe hundreds of files with API's working together, not just a bunch of algorithms.
As a seasoned developer I have come to realize that one of the most important things to be a good developer is organizational skills. Unfortunately it seems that ways to organize code bases, including things like naming, mutable state, modularization, cohesion/coupling, etc., are not as well developed or understood in general in our industry as they should be.
While understanding and knowing the right algorithms is important. I sometimes wonder if our emphasis on the knowing algorithms off the top of your head interviewing process contributes to putting the emphasis on the wrong things in software development.
10-20% of time in my career building business/productivity application systems have I needed to design & impl a complex algo.
Okay so my fictional team abstracts away that need and my algo guy colors in the deets. (In most cases this is possible; in rarer cases the performance of the algo needs to cross-cut.)
But the point is what you’re saying—one skill is pluggable, the other is not.
Kind of making this less interesting (or more?) is that learning algorithm dev tools/skills is far, far easier than learning the architectural/organizational skills. So no wonder the current prevailing hiring emphasis.
True, but I think any attempt to standardize or to make it another engineering discipline would mean the end of high programmer salaries. Just follow guidelines and standard procedure in a book and you'll end up with a reasonable solution that is reasonably good and reasonably reliable at a reasonable cost. Most businesses would jump at that...
And I'd argue that would be a good thing for all the sectors where programming is important, but no good programmer wants to actually join because its not sexy. (coal mining, medical equipment, etc)
> I sometimes wonder if our emphasis on the knowing algorithms off the top of your head interviewing process contributes to putting the emphasis on the wrong things in software development.
Yes but no business actually cares about creative solutions, unless algorithms are core to their business (and even then, other human factors outweigh finding the optimal, bestest, fastest solution). They simply want to use computers to solve a business problem. They want a runner to run from A to B, not an Olympic sprinter who is going to break a world record. Do you know a reasonably decent sort algorithm? Good, just use it. Profiling? Optimizing? That's for Olympic sprinters. Design patterns? Blindly apply a GoF design pattern that approximates your problem, etc etc.
Civil architects can be wildly creative and artful in their industry which understands its own domain deeply.
The field of software engineering is very nascent and is still in need of the underlying science and math foundations like you find in other engineering disciplines. Unfortunately methodologies like Agile and Waterfall seem to have become synonymous with software engineering.
I think it is more helpful to think of programming like other writing tasks. The difference in size and structure of programs is more like the difference between tweets, blog posts, shopping lists, poems, political essays, short stories, daily news articles, novels, anthologies, text books, academic articles, encyclopedias, court records, state constitutions, legislation, car repair manuals, and tomes by Russian authors.
Having standards and idioms for structure in writing doesn't remove the need for writing, creative input, nor even for creative exceptions to those standards and idioms.
>But that won't happen just by standardizing structure. The structure still holds content which has to adapt to those business goals etc.
I agree, but i'm thinking along the lines of - more LEGO, less literature. I.e. A move towards a more standardized problem specification process that itself becomes the solution, or at the very least through minimal effort.
That's what I see happening. There's already a huge reliance on just connecting together libraries within the confines of a framework for lots of problems.
I think you might live in a tech city bubble.
Outside of a few tech cities developer salaries are well below engineering salaries.
If development was treated more like engineering then developer salaries would go up. A lot.
Good programmers don't want to join these kinds of jobs because most normal businesses don't understand software engineering or the market and treat it like a cost center.
I started out my software career by writing vb macros in excel and saved my "boring business" company hundreds of thousands as a side effort to my normal job. Yet I couldn't get any traction to do it full time or to have autonomy or to get a meaningful (30-50%) pay increase to match the dev market salary.
As I've gotten older I've seen the value of this rule. Though it sounds merely negative, it can produce effects that seem little short of genius.
That means the duplication has to be highly significant and variations need to be few for it to pay off. ... And you'll better hope you have a good set of tests to verify everything is still working.
In most cases it's still a good idea, but it's still a case where you need to argue that you really need it, so it's no exeption at all.
[0] https://yosefk.com/blog/redundancy-vs-dependencies-which-is-...
https://www.joelonsoftware.com/2001/04/21/dont-let-architect...
Mind you, software developers aren't the only ones that cause this; a product owner / lead / whoever calls the shots is also very likely to keep bolting features onto a product. Either they have to keep that impulse down, or they too need a system to manage it. Also they shouldn't be afraid of culling existing features; what usually seems to happen is that more and more stuff is bolted on, until it's too much and they just rewrite the whole thing from scratch, leading to a clean, lean new application - often missing some features that older users like. Either they do it, or a competitor does.
Based on all the blogs and HN comments and comments here, that couldn't be further from the truth. Are these just things you learn from experience / mentors?
As far as where to learn these things: there are some books that talk about more broad topics than just how to use a particular tool/language. Those are more supplemental to experience/mentors, though.
There's an analogy I've heard, and I can't remember where. It might be a Feynman quote I'm recalling...
It'd be crazy to start design work on an airplane, if you're hungry and want to go to the corner store a block away for chips. It'd also be crazy to try to walk to China, since it's a long way, and also you might drown. The approach you take to solving the problem of getting from here to there depends completely on where here and there are, and what else you want to carry with you.
I don't use namespaces and build modules for an Arduino project, or a simple command line tool. But for large projects, I literally can't live without namespacing and modularization.
The core task of programming constitutes very different activities at different scales, as different as comparing walking to building jet engines.
In Haskell, for example, I can write software that does more things, using less code, with higher confidence that it’s correct, and much higher ability to change it, than I ever could in C++, my previous top language.
That’s partly the language, partly the fact that it matches my style of thinking, and partly the culture around it—writing reusable code, heavily encapsulating state, and making as much of your program as possible “correct by construction” so that invalid states and state transitions are inexpressible—or at least harder to express, such that the easy path is also the right one. A 500-line Haskell module tends to feel very large to me, on par with 1–2000 lines or so of C++.
I don’t necessarily mean to just evangelise Haskell or functional programming here. Any language & ecosystem with an expressive orthogonal core, which matches your problem space and not only matches but improves your style of thinking, can give you similar benefits if you’re deliberate about taking advantage of it.
Very good point. We’re all familiar with the “I can do ${lambda} in ${n} lines with ${lang} language”.
It seems to take me 10x more lines to do something in Java vs. Python, and 10x lines to do something in Python vs. Perl. Except that the Java is laborious to read, the Python is nicely readable, and the Perl will never be understood by a programmer.
I had great fun writing Perl many years ago but I used to joke that Perl was a “write only” language.
A year? I often lost a half day trying to understand Perl I’d written less than a week before. I’m not exaggerating.
I’m not sure what that says about me as a programmer but I’m terrified to find out.
Evidence is rare in our profession, but IIRC what little we have suggests no.
> If not, does it suggest we should be aiming to use more expressive languages, that can get more done in less lines?
Yes, it absolutely does. I recommend pursuing that approach.
I think we should be aiming for more expressive languages that can get more done in less lines, but I don't think that will have any affect on this phenomenon of hitting a wall once the complexity is high enough. The main issue is less about how expressive the language is, and more about whether you can read a section of code and easily understand it's limits and constraints and side effects. In non-functional C, it can be really hard to spot pointer bugs, where a more functional Python program might be easier to debug and maintain.
For me, I use Stepwise Refinement [3] to get to this point, but to get further, I have to start breaking out a more abstract approach. I found this definition of Structured Programming that puts it very nicely [4].
There's also a perhaps self-imposed wall, where you might trial a solution and implement a prototype, then use that to realize that it no point in pressing on without some serious redesign of a key component. For my example above, the rendering part is old-style OpenGL, which works pretty nicely at 60 fps, but I'm holding off doing more until I can slot in and benchmark a better approach using vertex buffers and shaders, with the goals of enabling me to shape and scale the renderings in an abstracted coordinate system, and scale to rendering hundreds of files instead of just one.
[1] https://twitter.com/watmough/status/962470455037841409
[2] https://twitter.com/watmough/status/965007110391128064
[3] http://www.informatik.uni-bremen.de/gdpa/def/def_s/STEPWISE_...
[4] https://www.encyclopedia.com/computing/dictionaries-thesauru...
and in 2015: https://news.ycombinator.com/item?id=10191540
I just finished the Python 2 -> 3 upgrade on it, that was fun.
I suppose that's close to what https://en.wikipedia.org/wiki/Kolmogorov_complexity is.
Maybe none of the problems we currently solve with computers actually demands beyond-the-wall programming, if we just used tools that were good enough. Certainly most of the time when automating business processes I would find it very hard to believe there was 20k lines' worth of essential, irreducible complexity in the task. It's just that with today's tools most of the lines we write are ceremonial, with relatively little describing the essence of the problem.
This could explain release dates getting pushed back :)
If it's just game scripting, then I could imagine it's possible to squeeze 2 mil lines out of junior devs. I assume there are very few things that can go drastically "wrong".
Repos were big. Really big. Especially since we're talking about people who will check in FMVs into source control.
Ah... what a horrible world.
what about kay vpri efforts to reduce a full system to 100K (OMeta)