3

3 Terrible Programming Features From the Past

 3 years ago
source link: https://medium.com/young-coder/3-terrible-programming-features-from-the-past-ee5260af1d74
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

3 Terrible Programming Features From the Past

These awful ideas died a rightful death years ago — mostly

I’m a strong believer in the programming truism that most bad features have a good reason to exist. The much hated goto statement can tunnel out of a deeply nested block structure quickly and cleanly, in experienced hands. A certain amount of type looseness lets code be leaner and less awkward. Memory pointers might make you hate life, but they were critically important for all the years that computer hardware was weaker than a Nest thermostat. And so on.

But then I think about these dusty old relics, and I realize that some old code ideas are so bad that the best action we can take is to kill them with fire. Without further introduction, here are 3 programming language features that are the stuff of nightmares.

1. On Error Resume Next (classic VB 6)

On Error Resume Next takes an approach that’s the worst idea in many error situations — just keep going! — and makes it the default rule for every problem. Imagine if we responded in the same way to real-life accidents. Had a car crash? Just keep driving!

' We'll set this just in case we have trouble connecting
' to the database.
On Error Resume Next Dim TotalPayment As Decimal
Dim TotalHours As Decimal
Dim HourlyRate As Decimal
TotalPayment = 5000' Oops forgot to set TotalHours!
' This shouldn't work, but we've got error immunity.
HourlyRate = TotalPayment / TotalHours ' Everything seems good. Let's update the database!
Call UpdateDatabase(HourlyRate)

But wait, it gets better. On Error Resume Next has no limit. It will work its way through long chains of errors that compound like interest from a bad Payday loan. It doesn’t even need to be at the top of your code module (stick it inline anywhere you want in your code, and switch back to normal when you’re ready with On Error Resume 0).

On Error Resume Next guarantees that you’ll reach the end of a code routine, which is a seductive bit of certainty. You don’t need to worry about some important bit of cleanup code being ignored. But you won’t arrive at your destination in quite the same shape as you started. It’s like an aggressive “fake it ’til you make it” strategy, except that there’s usually no way to “make it” after you’ve failed on a prerequisite task.

The only possible reason you might use On Error Resume Next is if you have no error handling code at all, and you just want to skip over all the not-so-bad problems that you’re ignoring. For example, maybe you’re knowingly creating a file that might already exist, setting printer property that might not be supported, or performing a calculation that might divide by zero. You are, objectively, not a good person in that instant. We forgive you. But if you use On Error Resume Next, you are compounding your ignorance by recklessly carrying on to a greater disaster.

But I won’t lie. I used it — and liked it — long before I actually learned to program. And now, it’s mostly dead. VB.NET, the current version of VB limping along in the .NET world, replaced On Error Resume Next with sensible structured exception handling. Or did it? It turns out that you can still use classic VB’s decades-old error-handling behavior in modern .NET, including On Error Resume Next. Which is insane, but thankfully I’ve never seen anyone try.

That said, On Error Resume Next still exists in real code. You can find it ruining macros in the Excel spreadsheet that the sales team uses. Thanks, VBA.

2. DoEvents (Windows Forms)

With a vaguely named built-in function like DoEvents(), you know you’re being set up for something ugly. And the Application.DoEvents() method does not disappoint.

DoEvents() is a once-popular but very dangerous kludge for Windows applications that don’t want to deal with multithreading. The classic scenario is updating the UI in a tight loop. For example, imagine you’re running a time-consuming mathematical operation and putting numbers into a list box. The user won’t see any of these numbers appear until you relinquish control and let Windows update the window. Typically, this doesn’t happen until your code runs to completion, unless you’re doing your work in the background on a separate thread.

DoEvents() asks your application to pause, just for a moment, so Windows can do whatever else it wants. So if you call DoEvents() in a loop, you’ll probably give the operating system a chance to repaint your window:

for (int i = 0; i < 1000000; i++) 
{
listBox.Items.Add(someCalculation(i)); // This is locking up the UI. We could refactor the code,
// or just add this wee workaround...
Application.DoEvents();
}

But the story goes downhill from here, and fast. The problem is that you never know exactly what DoEvents() is going to do. Other parts of your application may receive Windows messages (say, if the user clicks somewhere else), and they can start running their code in the space that you create when you call DoEvents(). This sounds bad, but it’s actually a lot of fun (if you like late-night debugging), because the result is just a little bit different on every computer!

As every programmer knows, the worst problem isn’t when something doesn’t work, but when it works on one computer but has just enough variability to fail mysteriously somewhere else. And if you don’t have this problem right now, DoEvents() has just enough nondeterminism to introduce it.

Of course, it’s also true that threading is hard. But for years .NET has had easy-to-use tools like the BackgroundWorker component, which lets you do all your work on another thread through a simple event-based model. There’s no need to hack it together with DoEvents(), and very few people do. And yet, it’s still there lurking in the class library, imported from old-school VB and currently accessible to every .NET language, including modern C#.

Embarrassing.

3. Dynamic Goto (COBOL)

Unlike the other issues I’ve discussed, this is a programming language horror that’s never affected me personally. (I may be old, but I’m not COBOL old.) But this feature is so remarkably insane that I couldn’t ignore it.

Imagine you were programming in an ancient language with cryptic flow control statements. Then you discovered that this language could alter its own code at runtime, changing the pathways it takes through different syntactical structures. Whimsical! If it works, everything is held together in a delicate balance. If it doesn’t work, you get something like the Worm of Ouroboros devouring its own tail.

The feature I’m calling dynamic goto is properly known as COBOL’s ALTER statement. It lets you alter an existing GO TO command so it actually transfers control to a different section than what’s written in your code. A GO TO statement can even be altered and re-altered, moved around to different parts of your code like a maze of highway off-ramps. Quite simply, ALTER takes everything you hate in GO TO — the confusing flow, the spaghetti code — and doubles down.

Here’s the sort of structure we’re talking about:

IF WS-X = 2 THEN         
ALTER SELECT-PATH TO PROCEED TO PATH-2.
ELSE IF WS-X = 3 THEN
ALTER SELECT-PATH TO PROCEED TO PATH-3.
END-IF.GO TO SELECT-PATH.SELECT-PATH.
GO TO PATH-1.

In this example, the GO TO SELECT-PATH command may take you to the SELECT-PATH label (which then sends you to PATH-1). But depending on the preceding variable test, it may be remapped to actually forward you to PATH-2 or PATH-3. And who knows what might have happened elsewhere in the code. In other words, you can’t say for certain where a GO TO will lead unless you’re familiar with the entire runtime history of the application. But don’t worry. I’m sure there’s a log somewhere that you can review.

You could call this metaprogramming, but most of us will just describe it as a Very Bad Idea.

1*y0RFKkLTndOShrp0CRhWPw.png?q=20
3-terrible-programming-features-from-the-past-ee5260af1d74

Arguably, on the underpowered computing equipment of the time, with a tiny call stack memory allocation, this sort of black magic made sense (maybe?). And — also arguably — there may have been a time when On Error Resume Next and DoEvents() were the best devil-I-know compromise for difficult problems. Today, some 60 years after the language was first created, the ALTER statement is considered obsolete and is scheduled for removal. So at least they’re doing the right thing.

The next time someone rightfully points out the quirks in JavaScript, or the madness of undeclared variables and implicit typing in any language, remind them — It could always be worse. It was worse.

Here’s hoping you never have the misfortune of meeting these horrors in an old codebase. And if you have your own favorite coding abomination of the past, drop it in the comments!

Subscribe to the Young Coder newsletter for a once-a-month email with our best tech stories.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK