This reminds me of an app we had at work for static content, written in JSP of course. It was made so designers and UI developers could make mostly static content pages.
Someone had a good idea to make a header.jsp template for common header stuff.
But it was hilarious. The file essentially became a giant if-else condition with a few hundred conditions like "if path == 'some_page'" followed by CSS and sometimes JavaScript for that page.
A brilliant tool I once worked with is TetGen; it takes a hollow 3D shape and creates a volumetric, space-filling mesh of the inside using tetrahedra. Most of what is TetGen is in once giant C++ file, clocking in at 36,566 raw SLOC.
We got many of these including a 13k LoC file in our OSS project. Yes, it isn't ideal but sometimes for performance and practical reasons these things grow over time.
In 2012 I worked on a jsp web app project, we replaced another consultant, so the project was inherited. A monstrous jsp page, of 13k lines IIRC, once traspiled to pure java hit the max length for a class method, 65535 bytes.
I'm guessing / hoping there was a lot of data in there as INSERT statements.
My horror story was being asked to do maintenance on PHP sites written in the early days of PHP. Hundreds - maybe thousands - of PHP files with copy-pasted HTML and intermingled logic. As far as I can tell, the idea of instantiating a whole MVC framework from a single entrypoint file came after that particular site was created, so every possible page was its own entrypoint with its own boilerplate. Source control also seemed to predate this project, so you had plenty of .old.php and .old.v2.php files.
Programming at webdev agencies is a challenging experience.
The number of lines in a file doesn't necessarily mean anything. SQLite is compiled as a single file: https://www.sqlite.org/amalgamation.html . It depends on the structure that is in that file.
If this app was factored into 300 different files, it would still be an impossible mess. The redundant and buggy logic would just be in different files.
I once inherited a mission-critical PHP project which had no version control, no tests, and no development environment (all edits were made directly on the server). It used a custom framework of the original author’s own devising which made extensive use of global variables and iframes and mostly lived in several enormous PHP files. I was able to clean it up somewhat, but there was one particularly important file that was so dependent on global variables and runtime state that I never dared touch it.
My first thought when reading this description was that step one is to make a local copy, get a development environment setup where you can toy around, see how things fit together. The 'stupid'er the setup (like using plain old files instead of a database), the easier that actually gets (apt install apache2 php; rsync da:files /var/www). Wouldn't that have helped solve this particularly important but untouchable file?
If I remember correctly, the file was processing global state from other parts of the system, and it was such a Byzantine bit of code that I had almost no hope of understanding what it was actually doing without being able to observe state in the production system as it was being used. Plus at the time I wasn’t a particularly competent programmer myself (this was my first programming job). In the end I figured it wasn’t worth risking breaking it when its replacement was on the way.
It wasn't mission critical but my very first production programming project (n.b. I'm not a programmer and never had any classical training or education as one) was an abomination. I'd like to think the realisation of how bad it was, despite it just about working, was a call to arms to up my game a little. I ended up learning a lot about data structures, writing understandable code and comment, when not to write code, all that OOP stuff and things like STI, Generics (still not sure what they are), testing (TDD AND BDD!!! Yea, Cucumber!) and a plethora of other useful things.
I once looked at 30 lines of code, analyzed them and found out that they always computed true, never false. My background knowledge told me that Zeit was the correct value. But I did not dare to eliminate it in the main branch, only in a refactoring branch that I think got never merged. I am not proud.
The thing is it’s easy to imagine a situation that leads to this. It’s five o’clock on Friday, your partner is hassling you to get home because you have visitors, you are exhausted because you worked 60 hours this week and your boss is breathing down your neck because they want their pet feature finished right now.
This is why I’m always loathe to criticise stuff I see on WTF.
I don’t remember if it did or didn’t have a single exit point.
But the thing as a whole didn’t follow any best practices I’ve ever heard of: the project also had what looked like a bizarre attempt to reimplement the concept of properties(!), in that the UI classes had fixed length arrays of all their subviews, which were accessed by constants. Each section of the UI had its own god class, where different views in that section were all the same class, called with a constructor that determined if a view ought to be created for any given constant.
There were also something like 20,000 blank comments. No idea why, the guy who added them didn’t even understand my question:
int something = foo();
//
double baz = bar(something, 5);
That kind of thing.
(The project is no longer available and the business who made it has since closed, before anyone asks).
I was being tongue in cheek about people who religiously follow that "single entry and single exit to any function" rule and then get wrapped around the axle when a function needs to make several discrete sanity checks at the start before doing work.
Debugging a single file is much easier compared to debugging a tangled mess of interconnected .h, .c, .tcc files with include directives that only work in a specific sequence and with a specific compiler.
Fix your include/import systems before preaching for modularity.
An early 2000s web analytics tool awstats was a 500kb Perl file. It was surprisingly easy to modify and hard to break - I spent a lot of time adding SEO goodies to it.
It depends how you see it: I see a project that is quite successful since it's running in production for mission-critical needs and the code is solid enough that even non-programmers can do improvements to it
If I remember correctly it was in fact written in Common Lisp; the output was originally that file but it may have been modified since. You can probably google the truth with those breadcrumbs :)
My company has REST client that is a single 9,000 line Go file that I have nightmares about. By my estimate it is really a ~300 line program written by someone who hated DRY.
More likely it was autogenerated from the API specs, if it hasn't been edited too much you might be the hero who made regenerating it part of the build.
For me the limitation of circular imports forced to drastically rethink how I architected my software (golang, rewrote the whole mvp 3 times be the first two I was either completely blocked by no-circular-imports or the structure felt so hacky that I didn’t even wanna touch it… then I learned about interfaces!!)
Just in passing, generally you can break circular import by isolating the coupling that triggers the circle chain in a file dedicated to that.
Bonus : each coupling use case gets to be explicit
Better one good organized file than 100s of folders and subfolders and files and symlinks. I have worked on projects where even after 2 years I didn't grasp the folder structure and just used search to locate files.
People love to complain about things that are simple, fast, and easy to complain about, without regard to whether the complaint is insightful or useful. It's sort of the dark twin of bikeshedding.
If you divide the single 11k-line file into a thousand 11-line files, it may become objectively much harder to understand, but it'll also receive much less flak, guaranteed.
I suspect this is also why Architecture Astronaut-ery can be so successful within a company. If code is chock-full of superficial signs of order and craftsmanship, such as hierarchy, abstraction, and Design Patterns(TM), it takes a lot of mental effort to criticize it, and most people won't.
is it different from regular bikeshedding? or are you saying that the dark twin is the evolutionary process of eg. architecture gaining complexity until it becomes difficult to criticize..
Bikeshedding is usually more about how something should be done than how it should not be done. But, yes, you could think of them as basically one thing.
If you divide a single 11k-line file into 20 files averaging 550 lines per each, by semantics and levels of abstraction, your code will quite possibly be easier to read, maintain and add to. Maybe. Perhaps.
I mostly agree, but it's often not that big a deal, and some people and applications may favor bigger files.
I have a 4000-line script in a single file that has served me very well. It's perfectly organized and modular. I thought about breaking it into more files but it seemed pointless. It's very convenient for jumping through every mention of a variable, for example.
> If you divide the single 11k-line file into a thousand 11-line files, it may become objectively much harder to understand, but it'll also receive much less flak, guaranteed.
A thousand 11-line files? You definitely could not make that guarantee of the people I work with.
No doubt dozens of devs will throw in their own 10k LOC story here, and yes it's painful to watch so many people having professional cramps over it.
But don't forget society itself if governed by OOM larger bits of text with no referential integrity, no machine to tell you if it's inconsistent, and no way to test anything, other than making humans write more text to each other and occasionally show up in court. The law itself, even parts of it like the tax code, and regulations on various areas, are a melange of text and cultural understandings between lawyers, judges and government. We collect the data for this machine in the form of contracts and receipts, and it piles up in mountains.
As with code, it's not just legal professionals who have to deal with law. It spills into everyone's life, and there's nothing to do about it other than either guess what to do or pay a pro to tell you what to do.
You are wrong to say there's no way to test anything. Imagine an enormous AI generating test cases for you constantly, in an adversarial fashion, with built-in rewards for advancing a more correct understanding of the text. Lawyers call this "testing", rightly so. If you are interested in efficiency / cost-effectiveness, it's got lots to be desired. But if you are interested in the internal integrity of the document etc, then this is better than almost anything developers have.
I hate these words as I type them but the law is also "agile" (ugh). It gets modified as it's used. It does not need high-assurance machine-verified "referential integrity". In my entire course of studying the law I don't think I've seen a single legal dispute over a problem of referential integrity. Mistakes, especially drafting mistakes, are corrected on the fly pretty much everywhere they appear, and then they disappear. For a dev, using the wrong variable name in a bad language could mean you introduce a huge security vulnerability and massive loss of trust. (Or if you write smart contracts, $100M down the drain.) For lawyers, referring to the wrong section has essentially zero consequences. Nobody cares. Maybe you get a funny look from a senior.
Finally re the 10k LOC tangent that this is supposed to be connected to, I'm not really sure what you're complaining about. You get "10kLOC" cases, but you also get well-organised practice guides & bench books. Laws in statute are typically very well organised, in my experience about 5-10x better than the average codebase. Laws are organising large swaths of the sum total of human endeavour, just as code does. I would say developers are behind overall, which makes sense for a discipline that's less than a century old.
The payroll check printer for my employer was once a couple thousand lines that generated raw PCL to be sent to a LaserJet that used magnetic toner to produce checks that had a working MICR number. It was rendered into spaghetti by multiple GOTOs that jumped to helpful labels like "666", and calls into other helper programs to generate more PCL that did things like change fonts and draw graphics. Of course none of it was commented, so you had to have a copy of the PCL spec on hand to know what any of it did. It was the product of a retired cowboy that had also written the rest of our custom payroll system over a number of years.
I attacked it by printing out and taping together each program into "scrolls" and tracing control flow with highlighters and sharpies. Had them all taped up on my office wall so I could refactor the whole thing from scratch, coworkers found that entertaining. Got a much more readable replacement working nicely. Then a couple years later HR bought a new system and we stopped printing our own checks. I was not sorry to see the whole thing go.
Reading your process I have that stereotypical TV series image in my mind of a person so deep into the subject matter that plaster every wall with notes and pull string all across the room at head height to hang up ever more notes kinda like that one NCIS episode (S8 E6 "Cracked"): https://img.sharetv.com/shows/episodes/standard/616591.jpg (although that image is only a small part of that whole view).
A printout of a one-file spaghetti code with gotos is the only case where I can imagine that trope of the wall of connected strings actually being a useful tool.
I went through something similarly during my PhD when my advisor printed the main code of the program that we were going to work on. At first I thought he was kidding (he's a very chill guy) but... Heck, after a few hours of "paper debugging" we discovered a lot of nasty issues, got new ideas and found redundant and spaghetti code that we didn't find when we debugged digitally (obviously, we were not a team of CS students/coders. Just a bunch of chemists kinda newbies to coding). It was a really useful and funny approach.
Unlike the OP's file, there's a rather substantial test suite and massive corpus of TypeScript code to work with, so at the very least, you'd have some grumpy people knocking on your door if you did something that negatively impacted the greater ecosystem.
Some documentation from Orta Therox on the checker:
If well done, single file projects are not bad. They save a lot boilerplate code. It is also easier to find things, since it is all in the same file.
EDIT: I'll go even further. Programmers who don't like long files are probably using the scrollbar to navigate around the file. Vim saves me from that bad habit.
What programming language requires 'a lot' of boilerplate code to use multiple files? That sounds awful. I don't think the argument for things being easier to find goes up either, with a tool like grep.
Perl XS (the system used to interface with C) requires module == file, so if you have a particularly large module then it just has to live in a single file. Here's one:
I've never written a file with 11,000 lines of code, but I have often built Clojure projects like this, with everything in one file. I think I might have once had a file with 4,000 lines of code. Maybe 5,000? A complete system might be 5 apps, working together, each made of one large file. It does help with some things. Especially if I try to on-board another programmer, if they don't know Clojure very well, using one file means they don't ever get tripped up by name spaces, instead, they just open one file, and then they can load it into the REPL and start working. I would not recommend this style for every project, but it does offer a kind of simplicity for the projects I work on.
345 comments
[ 2.3 ms ] story [ 363 ms ] threadSomeone had a good idea to make a header.jsp template for common header stuff.
But it was hilarious. The file essentially became a giant if-else condition with a few hundred conditions like "if path == 'some_page'" followed by CSS and sometimes JavaScript for that page.
Absolutely horrendous.
https://github.com/libigl/tetgen/blob/master/tetgen.cxx
My horror story was being asked to do maintenance on PHP sites written in the early days of PHP. Hundreds - maybe thousands - of PHP files with copy-pasted HTML and intermingled logic. As far as I can tell, the idea of instantiating a whole MVC framework from a single entrypoint file came after that particular site was created, so every possible page was its own entrypoint with its own boilerplate. Source control also seemed to predate this project, so you had plenty of .old.php and .old.v2.php files.
Programming at webdev agencies is a challenging experience.
Oof. That tbh sounds worse
If this app was factored into 300 different files, it would still be an impossible mess. The redundant and buggy logic would just be in different files.
When I was finally able to retire the project several years later, I first replaced the home page with this picture: http://2.bp.blogspot.com/-6OWKZqvvPh8/UjBJ6xPxwjI/AAAAAAAAOv...
The first project I inherited was PHP app that used a custom UI framework created by an agency that didn't work with us anymore.
One file had 7000 LoC and it would generate hundreds LoC of with-sprinkled JS code and send it to the browser on every click.
Debugging that thing was a nightmare.
I'm still not a programmer.
(The conditional in that if {} always evaluated to true).
var a = true;
if(a == true) then return true;
else if(a == false) then return false;
Or something like that.
This is why I’m always loathe to criticise stuff I see on WTF.
But the thing as a whole didn’t follow any best practices I’ve ever heard of: the project also had what looked like a bizarre attempt to reimplement the concept of properties(!), in that the UI classes had fixed length arrays of all their subviews, which were accessed by constants. Each section of the UI had its own god class, where different views in that section were all the same class, called with a constructor that determined if a view ought to be created for any given constant.
There were also something like 20,000 blank comments. No idea why, the guy who added them didn’t even understand my question:
That kind of thing.(The project is no longer available and the business who made it has since closed, before anyone asks).
Fix your include/import systems before preaching for modularity.
https://github.com/dotnet/runtime/blob/main/src/coreclr/gc/g...
https://github.com/python/cpython/blob/main/Python/ceval.c#L...
https://www.felienne.com/archives/2974
https://www.microsoft.com/en-us/research/blog/lambda-the-ult...
No metion of a cell-u-lite version.
Is that the same for all languages?
If you divide the single 11k-line file into a thousand 11-line files, it may become objectively much harder to understand, but it'll also receive much less flak, guaranteed.
I suspect this is also why Architecture Astronaut-ery can be so successful within a company. If code is chock-full of superficial signs of order and craftsmanship, such as hierarchy, abstraction, and Design Patterns(TM), it takes a lot of mental effort to criticize it, and most people won't.
is it different from regular bikeshedding? or are you saying that the dark twin is the evolutionary process of eg. architecture gaining complexity until it becomes difficult to criticize..
I have a 4000-line script in a single file that has served me very well. It's perfectly organized and modular. I thought about breaking it into more files but it seemed pointless. It's very convenient for jumping through every mention of a variable, for example.
A thousand 11-line files? You definitely could not make that guarantee of the people I work with.
But don't forget society itself if governed by OOM larger bits of text with no referential integrity, no machine to tell you if it's inconsistent, and no way to test anything, other than making humans write more text to each other and occasionally show up in court. The law itself, even parts of it like the tax code, and regulations on various areas, are a melange of text and cultural understandings between lawyers, judges and government. We collect the data for this machine in the form of contracts and receipts, and it piles up in mountains.
As with code, it's not just legal professionals who have to deal with law. It spills into everyone's life, and there's nothing to do about it other than either guess what to do or pay a pro to tell you what to do.
I hate these words as I type them but the law is also "agile" (ugh). It gets modified as it's used. It does not need high-assurance machine-verified "referential integrity". In my entire course of studying the law I don't think I've seen a single legal dispute over a problem of referential integrity. Mistakes, especially drafting mistakes, are corrected on the fly pretty much everywhere they appear, and then they disappear. For a dev, using the wrong variable name in a bad language could mean you introduce a huge security vulnerability and massive loss of trust. (Or if you write smart contracts, $100M down the drain.) For lawyers, referring to the wrong section has essentially zero consequences. Nobody cares. Maybe you get a funny look from a senior.
Finally re the 10k LOC tangent that this is supposed to be connected to, I'm not really sure what you're complaining about. You get "10kLOC" cases, but you also get well-organised practice guides & bench books. Laws in statute are typically very well organised, in my experience about 5-10x better than the average codebase. Laws are organising large swaths of the sum total of human endeavour, just as code does. I would say developers are behind overall, which makes sense for a discipline that's less than a century old.
I attacked it by printing out and taping together each program into "scrolls" and tracing control flow with highlighters and sharpies. Had them all taped up on my office wall so I could refactor the whole thing from scratch, coworkers found that entertaining. Got a much more readable replacement working nicely. Then a couple years later HR bought a new system and we stopped printing our own checks. I was not sorry to see the whole thing go.
Here's a TV Tropes article on the cliche: https://tvtropes.org/pmwiki/pmwiki.php/Main/StringTheory
https://github.com/microsoft/TypeScript/blob/main/src/compil...
Does anyone know why and how they maintain it?
Some documentation from Orta Therox on the checker:
https://github.com/microsoft/TypeScript-Compiler-Notes/blob/...
What does that even mean? It seems that typescript uses an alias for string as __String in the source but then a bitwise operator with string?
EDIT: I'll go even further. Programmers who don't like long files are probably using the scrollbar to navigate around the file. Vim saves me from that bad habit.