If you don’t care about programming languages, feel free to skip this entry.
This is probably more snark than I actually want to put out in the world. I just feel like I need to write this down because if left unexpressed, it’ll just fester.
I like a strongly-typed language. The more loosely/weakly typed a language is, the less help the compiler can give you in preventing errors, and the more cognitive load there is in writing correct code. This works fine in conversation — English, for example, is very loosely typed, and people speak to each other all the time in English — but it’s really a problem for idiot robots, which is what computers are.
Anyway, for reasons, I’ve been reading a lot of articles about Swift and networking and how great it is to have strongly-typed frameworks for all the reasons that type systems are, in fact, a good thing.
And as an aside, yes, strongly-typed languages do run up against some irritating difficulties when you want to have functions that don’t actually care what they’re passing along, they’re just reading bits from one place and writing them to another. Of course, that’s not actually what people use weakly typed languages for, in main — yes, yes, Perl is awesome for processing log files, but when was the last time you saw a disk I/O driver written in PHP? (Don’t @ me, that’s a rhetorical question.)
Anyhow. I’m going through some tutorials, to make sure I understand how Swift NIO works and here we go. I’m used to creating a socket and either accepting a connection on it (server) or opening a connection on it (client) and then reading bytes out of it and writing bytes to it. With NIO, the idea seems to be that there’s a channel, and then that channel has a pipeline, and that pipeline consists of a series of handlers. Each handler gets some input and has an opportunity to transform it or otherwise do some work and then write something, possibly else, back out, for the next handler to deal with. I love this model. That’s cool. However, here we go with the sticking point of strongly-typed languages. Handlers have to traffic in “whatever” and so the function is declared to handle a thing called NIOAny
.
So there are dedicated functions on the handler definition that take an NIOAny and turn it into whatever thing the handler actually expects the input or output to be, and to reverse the process. This is not a surprise, but I’m gonna go ahead and say it’s…sketchy. This is the part where we are, in C terms, “casting through void.” All the type safety up until now means that we’re probably going to be okay here, but this is the programming equivalent of Descartes’ tautology.
Anybody who is trying to tell you that Swift is great and the perfect thing because the strong type system prevents you from doing stupid things is trying to sell you something wretched or is an idiot, or both. There are no guarantees. Ultimately, when you get bits coming across an interface, you don’t know what the heck they are, you only guess. Once you’ve guessed, it’s really nice to write that down and let the compiler keep track of your guess so you don’t have to, but it’s still a guess.
Same thing happens when you archive an object to a file, right? I think you’re picking at nits.
You’re not wrong — basically, any time you send/receive outside the current process, you have to go through void. It’s a thing. And yet, I read these articles saying how Swift’s type safety makes certain classes of errors obsolete and I just think, “Yeah, buddy, you sure are putting a hell of a lot of trust in a human programmer whose previous claim to greatness is a Javascript shopping cart.”