![]() |
by Remy Porter on (#6VDFC)
There are real advantages to taking a functional programming approach to expressing problems. Well, some problems, anyway.Kevin sends us this example of elegant, beautiful functional code in C#:
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2025-02-20 18:47 |
![]() |
by Remy Porter on (#6VCM9)
Greg was fighting with an academic CMS, and discovered that a file called write_helper.js was included on every page. It contained this single function:
|
![]() |
by Remy Porter on (#6VBVS)
Gretchen saw this line in the front-end code for their website and freaked out:
|
![]() |
by Remy Porter on (#6VB4M)
One thing I've learned by going through our reader submissions over the years is that WTFs never start with just one mistake. They're a compounding sequence of systemic failures. When we have a "bad boss" story, where an incompetent bully puts an equally incompetent sycophant in charge of a project, it's never just about the bad boss- it's about the system that put the bad boss in that position. For every "Brillant" programmer, there's a whole slew of checkpoints which should have stopped them before they went too far.With all that in mind, today we're doing a news roundup about the worst boss of them all, the avatar of Dunning-Kruger, Elon Musk. Because over the past month, a lot has happened, and there are enough software and IT related WTFs that I need to talk about them.For those who haven't been paying attention, President Trump assembled a new task force called the "Department of Government Efficiency", aka "DOGE". Like all terrible organizations, its mandate is unclear, its scope is unspecified, and its power to execute is unbounded.Now, before we get into it, we have to talk about the name. Like so much of Musk's persona, it's an unfunny joke. In this case, just a reference to Dogecoin, a meme currency based on a meme image that Musk has "invested" in. This is part of a pattern of unfunny jokes, like strolling around Twitter headquarters with a sink, or getting your product lines to spell S3XY. This has nothing to do with the news roundup, I just suspect that Musk's super-villain origin story was getting booed off the stage at a standup open-mic night and then he got roasted by the emcee. Everything else he's ever done has been an attempt to convince the world that he's cool and popular and funny.On of the core activities at DOGE is to be a "woodchipper", as Musk puts it. Agencies Musk doesn't like are just turned off, like USAID.The United States Agency for International Development handles all of the US foreign aid. Now, there's certainly room for debate over how, why, and how much aid the US provides abroad, and that's a great discussion that I wouldn't have here. But there's a very practical consideration beyond the "should/should not" debate: people currently depend on it.Farmers in the US depend on USAID purchasing excess crops to stabilize food prices. Abroad, people will die without the support they've been receiving.Even if you think aid should be ended entirely, simply turning off the machine while people are using it will cause massive harm. But none of this should come as a surprise, because Musk loves to promote his "algorithm".Calling it an "algorithm" is just a way to make it sound smarter than it is; what Musk's "algorithm" really is is a 5-step plan of bumper-sticker business speak that ranges from fatuous to incompetent, and not even the fawning coverage in the article I linked can truly disguise it.For example, step 1 is "question every requirement", which is obvious- of course, if you're trying to make this more efficient, you should question the requirements. As a sub-head on that, though, Musk says that requirements should be traceable directly to individuals, not departments. On one hand, this could be good for accountability, but on the other, any sufficiently complex system is going to have requirements that have to be built through collaboration, where any individual claiming the requirement is really just doing so to be a point of accountability.Step 2, also has a blindingly obvious label: "delete any part of the process you can". Oh, very good, why didn't I think of that! But Musk has a "unique" way of figuring out what parts of the process can be deleted: "You may have to add them back later. In fact, if you do not end up adding back at least 10 percent of them, then you didn't delete enough."Or, to put it less charitably: break things, and then unbreak them when you realize what you broke, if you do.We can see how this plays out in practice, because Musk played this game when he took over Twitter. And sure, it's revenue has collapsed, but we don't care about that here. What we care about are stupid IT stories, like the new owner renting a U-Haul and hiring a bunch of gig workers to manually decommission an expensive data center. Among the parts of the process Musk deleted were:
|
![]() |
by Lyle Seaman on (#6V9H8)
Because we still have the NWS, I learned that "A winter storm will continueto bring areas of heavy snow and ice from the Great Lakes through New Englandtoday into tonight." I'm staying put, and apparently so is Dave L.'sdelivery driver.Dave L. imagines the thoughts of this driver who clearly turned around and headed straight home."Oh, d'ya mean I've got to take these parcels somewhere!? in this weather!? I can't just bring them back?"
|
![]() |
by Remy Porter on (#6V8N0)
Abdoullah sends us this little blob of C#, which maybe isn't a full-on WTF, but certainly made me chuckle.
|
![]() |
![]() |
by Remy Porter on (#6V70J)
As the saying goes, there are only two hard problems in computer science: naming things, cache invalidations, and off by one errors. Chris's predecessor decided to tackle the second one, mostly by accurately(?) naming a class:
|
![]() |
by Remy Porter on (#6V64W)
Andrew worked with Stuart. Stuart was one of those developers who didn't talk to anyone except to complain about how stupid management was, or how stupid the other developers were. Stuart was also the kind of person who would suddenly go on a tear, write three thousand lines of code in an evening, and then submit an pull request. He wouldn't respond to PR comments, however, and just wait until management needed the feature merged badly enough that someone said, "just approve it so we can move on."
|
![]() |
by Lyle Seaman on (#6V4B4)
I have a feeling we're going to be seeing a lot of AI WTFerry at this site for a while, and fewer stupid online sales copy booboos. For today, here we go:Jet-setterStewart wants to sell a pound, but he's going to have to cover some ground first."Looks like Google are trying very hard to encourage me to stop using their search engine. Perhaps they want me to use chatGPT? I just can't fathom how it got this so wrong."
|
![]() |
by Remy Porter on (#6V3GN)
Sammy's company "jumped on the Ruby on Rails bandwagon since there was one on which to jump", and are still very much a Rails shop. The company has been around for thirty years, and in that time has seen plenty of ups and downs. During one of those "ups", management decided they needed to scale up, both in terms of staffing and in terms of client base- so they hired an offshore team to promote international business and add to their staffing.A "down" followed not long after, and the offshore team was disbanded. So Sammy inherited the code.I know I'm generally negative on ORM systems, and that includes Rails, but I want to stress: they're fine if you stay on the happy path. If your data access patterns are simple (which most applications are just basic CRUD!) there's nothing wrong with using an ORM. But if you're doing that, you need to use the ORM. Which is not what the offshore team did. For example:
|
![]() |
by Remy Porter on (#6V2HB)
Tim has been working on a large C++ project which has been around for many, many years. It's a tool built for, in Tim's words, "an esoteric field", and most of the developers over the past 30 years have been PhD students.This particular representative line is present with its original whitespace, and the original variable names. It has been in the code base since 2010.
|
![]() |
by Remy Porter on (#6V1NM)
There are a lot of cases where the submission is "this was server side generated JavaScript and they were loading constants". Which, honestly, is a WTF, but it isn't interesting code. Things like this:
|
![]() |
by Remy Porter on (#6V0S1)
Just because you get fired doesn't mean that your pull requests are automatically closed. Dallin was in the middle of reviewing a PR by Steve when the email came out announcing that Steve no longer worked at the company.Let's take a look at that PR, and maybe we can see why.
|
![]() |
by Lyle Seaman on (#6TZ01)
Decreasingly hungry thrillseekerWeaponized Fun has second thoughts about the risk to which they're willing to expose their palate."In addition to Budget Bytes mailing list not knowing who I am, I'm not sure they know what they're making. I'm having a hard time telling whether 'New Recipe 1' sounds more enticing than 'New Recipe 3.' I sure hope they remembered the ingredients."
|
![]() |
by Remy Porter on (#6TY46)
I'm a JSON curmudgeon, in that I think that its type-system, inherited from JavaScript, is bad. It's a limited vocabulary of types, and it forces developers to play odd games of convention. For example, because it lacks any sort of date type, you either have to explode your date out as a sub-dictionary (arguably, the "right" approach) or do what most people do- use an ISO formatted string as your date. The latter version requires you to attempt to parse the sting to validate the data, but validating JSON is a whole thing anyway.But, enough about me being old and cranky. Do you know one type JSON supports? Boolean values.Which is why this specification from today's anonymous submitter annoys me so much:
|
![]() |
by Remy Porter on (#6TX6T)
Today's anonymous submitter spent a few weeks feeling pretty good about themselves. You see, they'd inherited a gigantic and complex pile of code, an application spread out across 15 backend servers, theoretically organized into "modules" and "microservices" but in reality was a big ball of mud. And after a long and arduous process, they'd dug through that ball of mud and managed to delete 190 files, totaling 30,000 lines of code. That was fully 2/3rds of the total codebase, gone- and yet the tests continued to pass, the application continued to run, and everyone was just much happier with it.Two weeks later, a new ticket comes in: users are getting a 403 error when trying to access the "User Update" screen. Our submitter has seen a lot of these tickets, and it almost always means that the user's permissions are misconfigured. It's an easy fix, and not a code problem.Just to be on the safe side, though, they pull up the screen with their account- guaranteed to have the right permissions- and get a 403.As you can imagine, the temptation to sneak a few fixes in alongside this massive refactoring was impossible to resist. One of the problems was that most of their routes were camelCase URLs, but userupdate was not. So they'd fixed it. It was a minor change, and it worked in testing. So what was happening?Well, there was a legacy authorization database. It was one of those 15 backend servers, and it ran no web code, and thus wasn't touched by our submitter's refactoring. Despite their web layer having copious authorization and authentication code, someone had decided back in the olden days, to implement that authorization and authentication in its own database.Not every request went through this database. It impacted new sessions, but only under specific conditions. But this database had a table in it, which listed off all the routes. And unlike the web code, which used regular expressions for checking routes, and were case insensitive, this database did a strict equality comparison.The fix was simple: update the table to allow userUpdate. But it also pointed towards a deeper, meaner target for future refactoring: dealing with this sometimes required (but often not!) authentication step lurking in a database that no one had thought about until our submitter's refactoring broke something. [Advertisement] ProGet's got you covered with security and access controls on your NuGet feeds. Learn more.
|
![]() |
by Remy Porter on (#6TWBZ)
Paul's co-worker needed to manage some data in a tree. To do that, they wrote this Java function:
|
![]() |
by Remy Porter on (#6TVJZ)
Denise's company formed a new team. They had a lot of low-quality legacy code, and it had gotten where it was, in terms of quality, because the company had no real policy or procedures which encouraged good code. "If it works, it ships," was basically the motto. They wanted to change that, and the first step was creating a new software team to kick of green-field projects with an eye towards software craftsmanship.Enter Jack. Jack was the technical lead, and Jack had a vision of good software. This started with banning ORM-generated database models. But it also didn't involve writing raw SQL either- Jack hand-forged their tables with the Visual Table Designer feature of SQL Server Management Studio."The advantage," he happily explained to Denise, "is that we can then just generate our ORM layer right off the database. And when the database changes, we just regenerate- it's way easier than trying to build migrations.""Right, but even if we're not using ORM migrations, we still want to write migration scripts for our changes to our database. We need to version control them and test them.""We test them by making the change and running the test suite," Jack said.And what a test suite it was. There was 100% test coverage. There was test coverage on simple getter/setter methods. There was test coverage on the data transfer objects, which had no methods but getters and setters. There were unit tests for functions that did nothing more than dispatch to built-in functions. Many of the tests just verified that a result was returned, but never checked what the result was. There were unit tests on the auto-generated ORM objects.The last one, of course, meant that any time they changed the database, there was a significant risk that the test suite would fail on code that they hadn't written. Not only did they need to update the code consuming the data, the tests on that code, they also had to update the tests on the autogenerated code.Jack's magnum opus, in the whole thing, was that he designed the software with a plugin architecture. Instead of tightly coupling different implementations of various modules together, there was a plugin loader which could fetch an assembly at runtime and use that. Unfortunately, while the whole thing could have plugins, all of the abstractions leaked across module boundaries so you couldn't reasonably swap out plugins without rewriting the entire application. Instead of making a modular architecture, Jack just made starting the application wildly inefficient.Denise and her team brought their concerns to management. Conversations were had, and it fell upon Jack to school them all. Cheerfully, he said: "Look, not everyone gets software craftsmanship, so I'm going to implement a new feature as sort of a reference implementation. If you follow the pattern I lay out, you'll have an easy time building good code!"The new feature was an identity verification system which called for end users to upload photographs of their IDs- drivers' licenses, passports, etc. It was not a feature which should have had one developer driving the whole thing, and Jack was not implementing the entire lifecycle of data management for this; instead he was just implementing the upload feature.Jack pushed it through, out and up into production. Somehow, he short-cut past any code reviews, feature reviews, or getting anyone else to test it. He went straight to a demo in production, where he uploaded his passport and license. "So, there you go, a reference implementation for you all."Denise went ahead and ran her own test, with a synthetic ID for a test user, which didn't contain any real humans' information. The file upload crashed. In fact, in an ultimate variation of "it works on my machine," the only person who ever successfully used the upload feature was Jack. Of course, since the upload never worked, none of the other features, like retention policies, ever got implemented either.Now, this didn't mean the company couldn't do identity verification- they had an existing system, so they just kept redirecting users to that, instead of the new version, which didn't work.Jack went on to other features, though, because he was a clever craftsman and needed to bring his wisdom to the rest of their project. So the file upload just languished, never getting fixed. Somehow, this wasn't Jack's fault, management didn't hold him responsible, and everyone was still expected to follow the patterns he used in designing the feature to guide their own work.Until, one day, the system was breached by hackers. This, surprisingly, had nothing to do with Jack's choices- one of the admins got phished. This meant that the company needed to send out an announcement, informing users that they were breached. "We deeply regret the breach in our identity verification system, but can confirm that no personal data for any of our customers was affected."Jack, of course, was not a customer, so he got a private disclosure that his passport and ID had been compromised. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
|
![]() |
by Lyle Seaman on (#6TST7)
"Math is hard, especially timely math," explainsThe Beast in Black.
|
![]() |
by Remy Porter on (#6TRZK)
A Representative Line is a short snippet that makes you think, "wow, I'd hate to see the rest of the code." A CodeSOD is a longer snippet, which also frequently makes you think, "wow, I'd hate to see the rest of the code," but also is bad in ways that require you to look at the relationship between the lines in the code.I bring that up, because today's code sample is a long section, but really, it's just a collection of representative lines. Each line in this just makes me die a little on the inside.Belda found this:
|
![]() |
by Remy Porter on (#6TR2B)
Sawyer was talking with a co-worker about how their unique session IDs got created. The concern was that they were only five characters long, which meant there could easily be collisions.They started by looking at the random number generation function.
|
![]() |
by Remy Porter on (#6TQ80)
Knowing the kinds of readers we have here, I strongly suspect that if you drew a Venn diagram of "TDWTF Readers" and "TikTok Users" those circles wouldn't overlap at all. But TikTok is in the news, and because my partner uses TikTok, I'm getting second hand smoke of all of this, I think there's some interesting things to talk about here.If you've been avoiding this news, good for you. For a long recap, Ars can bring up up to date.. But as a quick recap: TikTok is owned by Bytedance, which is based in China, and subject to Chinese laws. TikTok, like every other social media company, is basically spyware, tracking your behavior to sell your eyeballs to advertisers. Over the past few years, all three branches of the US government have decided that the "Chinese ownership" is the problem here (not so much the spying), and passed a law to ban it unless a US company buys it. The whole thing has turned into an idiotic political football, with Biden saying that his waning days of the Presidency wouldn't enforce the ban anyway, and then the whole thing turns into a Trumpist political football as the incoming President is playing Calvinball and making decrees that he did not (at the time) have any authority to make in the first place.Because of this ban, TikTok ceased operating in the US on Saturday night, displaying banners discussing the ban, and appeals directly to Trump to undo it. On Sunday, TikTok came back up, now with banners thanking Trump for being ready to work with them.Now, I'm mostly not interested in commenting on the political aspects of this, and you're mostly not interested in hearing it. But for the record: this whole thing is stupid. The root cause of the problem is that the US has no real consumer privacy law, but fixing that problem would be bad for companies like Google and Meta. So, instead, we play Whac-a-Mole with apps, dressing up Sinophobia as a national security threat, and we dance around the 1st Amendment issues. And then the whole thing of a President just deciding to rewrite a law at his whim is terrifying if you like the world to operate according to predictable rules, and presages a rather awful next four years.What I really want to talk about is conspiracy theories. Because when TikTok came back up, it was suddenly flooded with "IT professionals" who were positing a dark conspiracy: during the downtime, Meta purchased TikTok and migrated all of TikTok's services into Meta's infrastructure. That 12-15 hours of downtime was just the right amount of time to do that switcheroo.Now, I'm not going to link to any of these videos, because a) as stated, I don't use TikTok, b) TikTok requires you to use the app to watch videos, so screw that, and c) these people don't deserve more views. So there's an element of "take my word for it that this is happening," but also bear with me- because this isn't really what this article is about.Now, I am not a Site Reliability Engineer, and have no interest in being one. But I've worked with large retailers building global backends for point-of-sale systems where they're handling every point-of-sale transaction in the world. So I have some thoughts about the idea that migrating billions of videos and hundreds of millions of user accounts over to Meta's cloud can be done in 12-15 hours of downtime.Which, for the record, TikTok mostly uses Oracle's cloud, so add that to the "I Hate Oracle Club" scorecard.Let's assume Meta purchased TikTok. Would it have needed to spend 12-15 hours down so that Meta could migrate TikTok to their datacenter? Of course not. What an absurd thing to say. As this (Instagram) video rightfully points out, the only people taking down a website for a migration are a dentist office in Ohio in 2007. TikTok is a social media service handling hundreds of millions of users and billions of requests- they're already distributed across multiple datacenters. While spinning up services on a new datacenter isn't a simple task, it's a task that they've certainly already built the tools for. As part of their demand management system, they simply have to have the ability to spin up new service instances quickly and easily- at the scale they operate, that's the only option.They're a massive distributed system. Adding new infrastructure nodes and mirroring your data elsewhere is a solved problem. All it really takes is time and the budget to run more infrastructure than you need to service requests during the migration.The real costs are that if you're running in a cloud, you're likely not just using it as a set of virtual private servers- you're likely using your host's infrastructure-as-a-service abstractions, and that means that you might be tightly coupled to their implementation of a variety of cloud services. The real costs are that you'd need to make code changes to actually support a new cloud provider. And that's definitely not happening in a 12-15 hour time frame.But this is a dumb conversation to have, because if we assume Meta bought TikTok: there's no need to migrate anywhere. In this scenario, Meta has the keys to TikTok's infrastructure. Whatever they want to do, they can just... do. Sure, it means paying Oracle for hosting, but TikTok is making money. It's a net win. Over the next months or even years, Meta could move TikTok services into their private cloud and perhaps save costs, but there's no need to migrate on a tight timeline.Okay, so with all that said, what an idiot I am, right? Here I am, arguing against people I don't know, who definitely aren't going to read this. I don't even like TikTok, and think every social media app is a step down from just plain old RSS feeds, because I am an old person. We're deep into "someone is wrong on the Internet" territory. So why did this drive me up onto the soapbox?Because hearing all this conspiracy mongering nonsense reminds me of an important truth: everything looks like a conspiracy when you don't know how anything works.If you don't know how cloud deployments work, TikTok's downtime can look like a conspiracy. If you don't know how election systems are designed, any electoral result you don't like can look a lot like a conspiracy. If you don't know how the immune system works, vaccines can look like a conspiracy. If you don't know how anything works, a flat Earth starts making sense.Realistically, no one of us can know how everything works. In an ideal world, we can defer to experts who do know how things work. But to defer to experts, we need to trust expertise.And as a society, trust in experts has been eroding. A lot of it comes from propagandists who want their ignorance to be valued at least as highly as expertise. Being loudly wrong about things is a great way to get attention and with that, money. Alex Jones made many millions being loudly wrong.But it's not just loudmouthed morons that are eroding the trust in experts. Experts can and have abused the public trust. The poster child for "Worst Person Ever" is Thomas Midgely, Jr., who lied to the public and created a gigantic public health disaster, then went on to create a gigantic environmental disaster (in his defense, CFCs destroying the ozone layer wasn't something he knew about, but he absolutely knew about the dangers of leaded gasoline).And even more than that, in a society where peoples' prospects look worse with each passing year, with entire generations deciding that buying a home and having children are just going to be out of reach, we have to ask: what good is it to listen to experts if it doesn't lead to good outcomes? When all the experts work for a big mega corporation and put their big brains to work figuring out how to turn my eyeballs into dollars, or are working for think tanks and government agencies captured by those corporations, what good are experts?All in all, it looks bleak. There's no easy fix for any of this. The systems which make expertise viable have eroded over the past decades, taken for granted. Public trust in just... everything has weakened. Fixing this requires broad social changes. A minor tech blog that focuses in the ways people screw things up is not going to drive broad social changes.But I think there's one thing I can drive from here, and it comes back to this one simple statement: everything looks like a conspiracy when you don't know how anything works.So, I'm going to put out this call: when you know how things work, share that. Share what you know! Share it on social media. Share it on your own personal blog. Share it in local meeting groups. Hell, share it on TikTok, because gods know, they need it.But also don't forget the flip side: when you don't know, be careful about finding conspiracies. When you don't know how something works, it might look like a conspiracy. But, frequently, it's not- you're just ignorant. And honestly, we should be as open about our ignorance as we are about our knowledge. We should know what we don't know, or at least know when we're stepping outside of our areas of confidence.So let me close with this: do you have a place you're sharing the things you know? Do you think it'd be of interest to our readers? Use our submission form, and use the subject/title "Reader Link". If I get enough interesting links, I may do a roundup of them.Tomorrow, we'll return to our regularly scheduled programming. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
|
![]() |
by Remy Porter on (#6TPEM)
Janet's company had a glut of work, and thus didn't have the staffing required to do it all. It didn't make sense to hire on any new full-time employees, so they went the route of bringing on a few highly paid consultants, specifically ones who specialized in one specific problem: talking to a piece of hardware purchased from a vendor.The hardware in question was a scientific which communicated over a serial line. This device provided a lot of data that represented decimal values, but that data was not encoded as an IEEE float. Instead, they used two integers- one for the data, and one representing the number of decimal places.So, for example, "555.55" would be represented as "55555 2".Now, in embedded devices, this isn't too unusual. It's entirely possible that the embedded CPU didn't even support true floating point operations, and this was just how they decided to work around that.When communicating over the serial line, the device didn't send the data encoded in binary, however- it did everything as text. This was arguably helpful as it meant a technician could communicate with the device directly over a terminal emulator, but it meant any software talking to the device had to parse data.Which brings us to the code written by the highly paid consultants. This code needs to take two 16-bit integers and turn them into a single decimal value. Let's see how they did it.
|
![]() |
by Lyle Seaman on (#6TMQ4)
Casanova Matt swings for the fences."OKCupid (they don't capitalize the K, but I do, for propriety)must have migrated their match questions through Excel duringa recent site revamp. These answers should obviously be 1-2and 3-4, but maybe I could have 2 with Jan and 4 with Margaret(Mar to friends)."
|
![]() |
by Remy Porter on (#6TKT9)
Roger took on a contract to fix up a PHP website. During the negotiations, he asked some questions about the design, like, "Is it object-oriented or more procedural?" "No, it's PHP," said the developer.Which about sums it up, I suppose. Have some date handling code:
|
![]() |
by Remy Porter on (#6TJYF)
Keige inherited some code which seems to be part of a drawing application. It can load brush textures from image files- at least, sometimes it can.
|
![]() |
by Remy Porter on (#6TJ38)
David was integrating a new extension into their ecommerce solution, and found this un-representative line:
|
![]() |
by Remy Porter on (#6TH8F)
Grun works for a contracting company. It's always been a small shop, but a recent glut of contracts meant that they needed to staff up. Lars, the boss, wanted more staff, but didn't want to increase the amount paid in salaries any more than absolutely necessary, so he found a "clever" solution. He hired college students, part time, and then threw them in the deep end of Perl code, a language some of them had heard of, but none of them had used.It didn't go great.
|
![]() |
by Lyle Seaman on (#6TFFE)
Someone online said we run a Mickey Mouseoutfit. Angered beyond words, we consulted legal@disney.com and they threatened to findthat guy and sue him. So to anyone else who thinks this column is Goofy, you should know that the world's definitive authorities insistthat it absolutely is not.But these guys? This website actually iskind of goofy, according to resolutioner Adam R. who crowed "Someone forgot to localize some text for the new year!"
|
![]() |
by Remy Porter on (#6TEM2)
Antonio's team hired some very expensive contractors and consultants to help them build a Java based application. These contractors were very demure, very mindful, about how using ORMs could kill performance.So they implemented a tool that would let them know any time the Hibernate query generator attempted to perform a cross join.
|
![]() |
by Remy Porter on (#6TDRF)
Bejamin's team needed to generate a unique session ID value that can't easily be guessed. The traditional way of doing this would be to generate cryptographically secure random bytes. Most languages, including PHP, have a solution for doing that.But you could also do this:
|
![]() |
by Remy Porter on (#6TCT4)
Today's anonymous submission is a delightfully simple line of JavaScript which really is an archetype of a representative line.
|
![]() |
by Remy Porter on (#6TBX5)
Ted's company hired a contract team to build an application. The budget eventually ran out without a finished application, so the code the contract team had produced was handed off to Ted's team to finish.This is an example of the Ruby code Ted inherited:
|
![]() |
by Lyle Seaman on (#6TA9W)
Happy 2025 to all our readers. I can already tell thisyear's columns are going to be filled with my (least)favorite form of WTF, the impossible endless gauntlet offlaming password hurdles to jump over or crawl under. Please comment if you know why this week's column has this title and why it doesn't have the title Swordfish.Peter G. starts off our new year of password maladies with a complaint that is almost poetic.
|
![]() |
by Remy Porter on (#6T9FQ)
Ash's company outsourced to an offshore vendor.This is an example of what they got back:
|
![]() |
by Remy Porter on (#6T8ZK)
Twenty five years ago today, the world breathed a collective sight of relief when nothing particularly interesting happened. Many days begin with not much interesting happening, but January 1st, 2000 was notable for not being the end of the world.I'm of course discussing the infamous Y2K bug. We all know the story: many legacy systems were storing dates with two digits- 80 not 1980, and thus were going to fail dramatically when handling 00- is that 1900 or 2000?Over the past few weeks, various news outlets have been releasing their "25 years later" commentary, and the consensus leans towards this was no big deal, and totally fine. Nothing bad happened, and we all overreacted. There may have been some minor issues, but we all overreacted back then.So I want to take a moment to go back to the past, and talk about the end of the 90s. Let's go for it.via GIPHYIt's the End of the World as We Know It25 years on, it's really hard to capture the vibe at the close of the 90s. We'll focus on the US, because that's the only region I can speak to first hand. The decade had a "it was the best of times, it was the worst of times," aspect to it. The economy was up, lifted in part by a tech bubble which had yet to pop. The AIDS epidemic was still raging (thanks, in part, to the disastrous policies of the Reagan administration). Crime was down. The Columbine Shooting was hitting the national consciousness, but was only a vague hint of the future of mass shootings (and the past, as mass shootings in the US have never actually been rare). The Soviet Union was at this point long dead and buried, and an eternal hegemony of the US seemed to be the "end of history". On the flip side, Eastern Europe was falling apart and there was war in Kosovo. Napster launches, and anti-globalization protests disrupt cities across the country.Honestly, I feel like Woodstock '99 sorta sums up the last year of the decade. A music festival with a tradition of love and peace is wildly unmanaged and held in a hostile environment and devolves into chaos, violence, and sexual assaults.With the millennium looming, people were feeling weird. There was a very real sense that the world was coming to an end. Not literally, but the sense of a looming apocalypse of some king was inescapable. It's easy to be the rational one and say, "this is just an arbitrary mark on an arbitrary calendar, it doesn't mean anything", but the mass public and the zeitgeist at the time wasn't feeling rational.When you add the Y2K bug into the mix, people lost their goddamn minds.The Vibe of Y2KWe'll talk about the technical challenges of the Y2K bug, but honestly, I think it's less interesting than the vibe.What people knew was this: computers ran the world, and at midnight on December 31st, 1999, every computer was going to freak out and try and kill us. Don't take my word for it.Honestly, would anyone have cared if the Backstreet Boys climbed into a bunker in 1999? That feels like the end of their reign as the boy band of the moment. Even Dr. Dre, who is clearly trying to be reasonable, doesn't want to be on a plane that night. Christina Aquilera's mom told her not to use elevators.Or check this guy, who's less afraid of the technical problem and more "the social" one:It wasn't all panic, like this long segment from the Cupertino City Council:And certainly, hero of the site Peter, knew it was boring and dry:But NYE 1999, people were unplugging all their appliances so the computers in them wouldn't freak out. In the run up, people were selling books to help you prep. Survival guides abounded. Some of them took this as a dire warning about the dangers of global warming and sexuality in media.The public poorly understood what Y2K meant, but were primed to expect (and prepare for) the worst. From this distance of hindsight, we can see echoes of the panic in the response to the COVID pandemic- a very real problem that people wildly misunderstood and reacted to in all sorts of insane ways.The ProblemLet's get back to this idea of "some programs represented years with two digits". From the perspective of a modern programmer, this seems weird. It sounds like we were storing dates as stringly typed data, which would be a really silly thing to do.So I want to discuss the kinds of systems that were impacted and why. Because in the 90s, people thought their PCs might blow up at the changeover, but your desktop computer was never really at any risk. It was legacy mainframe systems- the big iron that ran half the world- that was at risk.To understand the bug, and why it was hard to fix, we need to spend some time talking about how these systems worked. Well, work, because there are certainly a few still in use.We're going to focus on COBOL, because I've had the misfortune to work with COBOL systems. Take my examples here as illustrative and not "authoritative*, because there are a lot of different kinds of systems and a lot of different ways these bugs cropped up.Now, as a modern programmer, when we think about representing numbers, we think about how many bits we dedicate to it. An 8-bit integer holds 256 distinct values.Mainframe systems used "flat file databases". As the name implied, data was stored in a file- just dumped into that file with minimal organization. A single application may interact with many "flat files"- one holding customers, one holding invoices, and so on. There were no built-in relationships or foreign key constraints here, applications needed to enforce that themselves. On a single mainframe, many programs might interact with the same set of files- the accounts receivable program might interact with invoices, the shipping supervisor would also look at them to plan shipping, an inventory management program would update inventory counts based on that, and so on.These interactions could get complex on any given system. And those interactions could get more complicated because multiple systems needed to talk to each other- so they'd need data interchange formats (like EDI or ASN.1).In COBOL, you'd describe your flat files with a "data division" in your program. That data division might look something like this:
|
![]() |
by Remy Porter on (#6T8DC)
|
![]() |
by Remy Porter on (#6T7PK)
|
![]() |
by Lyle Seaman on (#6T656)
The Hatter was framed! He didn't even do it! Nil Corpus Delecti, et cetera.Yet Yitz O., up to some kind of skullduggery, observed a spacetime oddity."When trying to compare some results from a GetOrders call via the ebayapi, I noticed something weird was happening with the DateTimes in the response.The attached is 3 calls to get the same order, made in quick succession.The millisecond part of all the DateTimes matched the millisecondpart of the *current* time (which you can see in the TimeStamp field.I assume it's because they rolled their own DateTime functionalityand are Getting a UTC time by subtracting the difference betweenthe local time and the UTC time, and one of those values doesn't havethe millisecond value in it, but it's the ebay api so who knows."Undoubtedly a bug that nobody ever noticed because they probablyjust ignore the millis altogether.
|
![]() |
by Remy Porter on (#6T5JC)
|
![]() |
by Remy Porter on (#6T56C)
Last year, we spent our Christmas looking at some Christmas movies and specials, and rated them based on the accuracy of their portrayal of the IT industry. We're going to continue with that this year. Just like last year, we'll rate things based on a number of floppy disks- means it's as accurate as Office Space, whereas puts it someplace down around Superman III.GremlinsTechnology has conquered the world, but none of it actually works. As Mr. Futterman (played by the classic character actor Dick Miller) points out: they've all got gremlins in them. Except, thanks to a goofy dad's last minute Christmas gift and some careless 80s teens, the gremlins aren't just taking over technology, but the entire town with their goofy violence.This was the most mentioned film left out last year. As far as tech industry representation, we've got a lot to discuss here. First, the father who purchases Gizmo- the Mogwai that becomes the source of all the gremlins- is an inventor. This is the 80s, and thus we're all recovering from the fads of Rubik's Cubes and Pet Rocks, so Randy Petlzer is trying to crash whatever the next fad is. He's got a collection of goofy gadgets, including the orange juicer above, which is itself a premonition of the Juicero startup, itself a goofy disaster of venture capital.An independent inventor with no real business model but a bunch of goofy ideas also thinks he's a genius. Where have I heard that before? At least, he did "read the manual" (listened to the instructions given to him by the very 80s orientalist stereotype) and even communicated them, so credit to that. But nobody actually followed those instructions anyway, which leads to all the chaos. Do you think I used the word "goofy" enough to describe this movie? It's very goofy, and I think it's gotten goofier with age, honestly. Without nostalgia, I wouldn't call it good, but it is goofy.The highlight of the film is Phoebe Cates's monologue about why she hates Christmas: a grisly tale about her father's death.Rating:The ApartmentBud Baxter has an apartment conveniently close to work- so convenient that all the executives at his company bring their mistresses there. It's great for Bud's career, but less good for his reputation and his own personal love life.So, this may be a stretch as Christmas movies go. It takes place around Christmas, but doesn't have a lot of Christmas themes. You know what it does have? A load of entitled management types who not only control Bud's life around the office, but his life at home, and definitely don't care about how that affects him. If this were in 2024, they'd be using bossware to track him and smart door locks to keep him out of his own house.Rating:The Knight Before ChristmasA modern gal in Ohio has given up on love. A 14th century knight is magically transported to Ohio. Together, they discover the true meaning of Christmas- and love.This is Netflix's stab at a Hallmark level Christmas movie. The whole thing revolves around the Ohio town having a Christmas tradition of erecting a "Christmas Castle" and doing a pseudo-Ren Faire thing every Christmas which is not, as far as I know, a thing anywhere, except perhaps a few small towns in Europe, where they have naturally occurring castles. Our gallant knight gets to be flummoxed by modern technology, like the Alexa, but basically figures all this stuff out over the course of a few days.For IT accuracy, this is definitely:Rating:However, it's also worth noting that the plot kicks off with our modern gal hitting the befuddled knight with her car at the Christmas Castle. They go to the hospital, where everyone assumes he's an actor from the Castle, and now has amnesia after being hit by a car. Since he has no ID, instead of providing medical care for what they believe to be severe brain damage, they just... let her take him home with her. So, if we were rating this for accurately representing the health care system in the US:Rating:The Bear: Feast of the Seven Fishes"The Bear" focuses on Carmy, who is trying to turn his deceased brother's sandwich shop into a Michelin rated fine-dining restaurant. This episode flashes back to a Christmas before his brother died, and shows us what his family life was like, as his mother prepares the traditional "Feast of the Seven Fishes" for Christmas.So, unlike Christmas Castles, Feasts of Seven Fishes are real. I grew up with the loud Italian family. My grandmother was so Italian she came through Ellis Island and also had one of these to point at her Christmas Tree. We did not do the complete Feast of the Seven Fishes, because nobody wanted to work that hard, but deep fried kippers were always featured. These were whole fish, which you'd eat. Bones, faces and all. That was fine, but I was honestly really there for the ginettes (everyone else calls them anise cookies, but we called them ginettes).Our Christmas wasn't as stressful as Carmy's, and while folks got drunk, it was strictly "the old guys drink too much and fall asleep in their chairs" levels of drunk.Rating:Dominic the DonkeyWhen Santa wants to visit his "paisans" in Italy, his reindeer can't handle the hills- so he relies on his friend, Dominic, the Italian Christmas Donkey.Look, I had to suffer through this song growing up, so now you do to. Hit play. Put it on loop. You're trapped in here with us. Jingety jing! HEE HAW HEE HAW! IT'S DOMINIC THE DONKEY.Rating:The Iron GiantAn alien war-bot crashes on Earth and gets amnesia, forgetting that it's a war-bot. Young Hogarth befriends the bot, and adventures ensue. Meanwhile 1950s Fox Mulder tries to track down the "monster" and put a stop to the Communist threat it represents.I know what you're saying: "there's nothing Christmas here!" But, based on this list so far, amnesia is a Christmas tradition! Setting that aside, I'm not religious, but if we're talking about keeping the "Christ" in "Christmas", you can't do better than a giant robot who dies for our sins and is reborn days later. Honestly, the Bible could have used more giant robots. Maybe a Godzilla or two. While the movie leans hard into Superman as its metaphor for heroism, Superman has frequently been appropriated as a Christ metaphor. Which, there's a whole lot to unpack there, given that Superman's creators were Jewish.This story features incompetent government agents trying to regulate technology they don't understand. While the film colors it in with Red Scare tones, it echoes the same constant shrieking from the FBI and NSA that regular citizens shouldn't have access to strong encryption (and they need a magical backdoor into all encryption algorithms to keep you SAFE). Or the countless "think of the children!" bills that attempt to police the Internet and always fail. Or the classic "Felony Contempt of Business Model"- the sections of the DMCA that make it illegal for you to refill your printer cartridges or jailbreak your phones.Rating: [Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
|
![]() |
by Remy Porter on (#6T4P9)
Mihail was excited when, many years ago, he was invited to work for a local company. At the time, he was in college, so getting real-world experience (and a real-world paycheck) sounded great. It was a small company, with only a handful of developers.The excitement didn't last long, as Mihail quickly learned what the project was: parsing commit messages in source control and generating a report of how many hours a developer worked on any given task. It was a timesheet tracking application, but built on commit messages."This... seems like a bad idea?" Mihail told his supervisor. "Couldn't we just do this in a timesheet tool? Or heck, a spreadsheet? Accounting would probably prefer a spreadsheet.""If we did that, people could edit their numbers," the supervisor responded.Apparently they hadn't heard about amending commits. Or just... lying in the commit message?Now, Mihail wasn't allowed to start working. A design document needed to be crafted first. So several senior developers went into a room, and hammered out the design. Three weeks later, they had a basic structure of five classes: components, which were made up of milestones, which were made up of tickets, which had contributors, which made commits. It wasn't a complicated design, so it was mystifying as to why it took three weeks to write. More problematic- the project had only budgeted a month, so Mihail was left with a single week for implementation.One frantic week later, Mihail handed in his work. It was insufficiently tested, but more or less worked according to the design. He had to take a week off of work for exams, and when he returned from those exams, the senior devs had some good news and bad news. The good news: they were happy with his work! The bad news: during the week the design had been completely changed and needed to be rewritten.So the rewrite began, with a new design, and once again, too little time left to do the work. Tests went out the window first, but "basic coding practices" quickly followed. The second version was less reliable and usable than the first. Then the Big Boss sent down an edict: this whole system should get its data from their bug tracker, which had SQL integration options.Once again, it was all thrown away, and a new version began. Mihail started writing queries for the database, starting by joining the three key tables to produce the data they wanted. Then he read the new version of the design doc, published while he was working, and joined the five tables together they'd need. After combining the six tables the design doc called for, Mihail was starting to think the code he was writing was bad.The workflow that the design called for offered it's own challenges. After writing the query which joined eight tables together, with a nest of subqueries and summaries, the query itself weighed in at 2,000kb. And that was just for one report- there were a dozen reports that were part of the project, all similarly messy, and all subject to rapidly changing design documents. The queries were all hard-coded directly in a Python script, and the design was explicit: don't slow down developers by using prepared statements, just use string concatenation (aka SQL injection) because we can trust our inputs! This Python script would run its reporting queries, and then dump the results into tables in the application's database. Then a web UI would pick up the data from the tables and show it to the user.The only thing we can say about the results is that the web UI looked nice. The underlying horror that was the code was hidden.With the project finally done, it was time to show it off to upper management. Mihail's supervisor starts demoing their system, and after a minute, the Big Boss pipes up: "Why do we need this?""Oh, well, it's a more flexible-""No. Why do we need this?""Time tracking is fundamental to our billing-""Right, but why do we need this? You know what, never mind. Do whatever you want with this, just make sure that all the data ends up in an Excel spreadsheet at the end of the month. That's what we send to accounting."All in all, Mihail spent six months working on this project. Once complete, it was never used by anyone. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
|
![]() |
by Remy Porter on (#6T3Z7)
Rachel worked on a system which collected data about children, provided by parents and medical professionals. There was one bug that drew a lot of fire: no one could report the age of a child as less than one. That was a problem, as for most of their users, child ages are zero-indexed. One of the devs picked up the bug, made a change, and went on to the next bug.This was the fix:
|
![]() |
by Lyle Seaman on (#6T2BS)
Rational Tim R. observed "When setting up my security camera using the ieGeek app thereseem to be two conflicting definitions of sensitivity. I hopethe second one is wrong, but if it's right, I reallyhope the first one is wrong."
|
![]() |
by Remy Porter on (#6T1JZ)
Michael had a co-worker who was new to the team. As such, there was definitely an expected ramp-up time. But this new developer got that ramp up time, and still wasn't performing. Worse, they ended up dragging down the entire team, as they'd go off, write a bunch of code, end up in a situation that they couldn't understand why nothing was working, and then beg for help.For example, this dev was tasked with adding timestamps to a set of logging messages. The logs had started as simple "print" debugging messages, but had grown in complexity and it was time to treat them like real logging.This stumped them, as the following C# code only ever printed out a zero:
|
![]() |
by Remy Porter on (#6T0PT)
Conditional statements, we would hope, are one of the most basic and well understood constructs in any programming language. Hope, of course, is for fools and suckers, so let's take a look at a few short snippets.Our first installment comes from Jonas.
|
![]() |
by Remy Porter on (#6SZV0)
Joseph sends us a tried and true classic: bad date handling code, in JavaScript. We've all seen so much bad date handling code that it takes something special to make me do the "confused dog" head tilt.
|
![]() |
by Remy Porter on (#6SZ3B)
Today's anonymous submitter supplies us with a classic antipattern: padding via switch:
|
![]() |
by Lyle Seaman on (#6SXE6)
The weather isn't the only thing that's balmy around this parts.For instance Bruce, who likes it hot."Westford, MA is usually bracing for winter in December,but this year we got another day of warm temperatures. The feels like temperature was especially nice."
|