Press "Enter" to skip to content

Posts tagged as “Programming Parables”

[twenty twenty-four post fifty-one]: worse than useless

centaur 0

So I recently came across a tutorial for game development that seemed pretty interesting, so I decided to give it a try. The tutorial was in Rust, a new language that I’d been hearing about, and so I thought it would be a good idea to learn that too.

I even found an online playground, https://play.rust-lang.org/, which lets you try out the language in the browser, much like the Go playground: https://go.dev/play/. I quickly started trying out some simple functions that I use a lot in a variety of languages …

… and got stuck right away on Rust’s lack of function parameters.

There’s a whole blogpost https://www.thecodedmessage.com/posts/default-params/ on why this antifeature is actually, in the minds of “Rustians,” is a good thing, but even that admits that the alternatives that the language provides “might seem worse than useless.” 

I’m sorry, I’ve gone through this kind of Stockholm Syndrome thinking before, where users held hostage to the good features of a language start coming up with excuses for its warts. For example, take the Go programming language. Programming Go felt like a breath of fresh air, but it was literally worse than useless for my use case - I had to write the software I wanted in C and then call it from Go. And the language itself had terrible warts from the terrible choices made by the core Go team - at the time I used it, no support for generics, endless proliferating error checks, and worst of all, an overly verbose unit test style which threw out everything we’d learned from Java and Python about how to write tests using semantically meaningful methods like assertIsNotNone or assertIsEmpty.

I’m not saying I’m not going to not learn Rust, nor that I’d never use Go again. Hey, one day I may be a convert! But, based on what I know now, I would never recommend these languages to anyone. My recommendations for programming languages remain the same "Big Three, Plus One": 

  • For most tasks, use Python. 
  • If you need speed, use C++.
  • If you work with a very large enterprise, consider Java.
  • If you’re working with a system that uses a specific language, use that language: C in the Linux kernel, Javascript on the web, Swift in iOS, Java in Android, PHP in WordPress, C# for Unity, and so on.

Many of the alternative languages that you can use - Go, Rust, Scala, Clojure, even my beloved Mathematica, Common Lisp, or J - are actually worse than useless for most tasks, for two reasons. 

  • First, most of them are less baked than the Big Three, and are less ready for developing real applications; they’re not chosen for their fitness to purpose, but instead chosen by zealots who are trying to make a point. Don’t be a zealot trying to make a point.
  • Second, working on these other languages actually detracts from making the Big Three better. The C++ of today is almost unrecognizably usable compared to when I first started using it, and Python and Java are rapidly adding new usability features as well.

That doesn’t mean we don’t try new things. C++ has mostly replaced C, and TypeScript is edging out JavaScript; who knows, perhaps, one day some variant of Go or Rust or Swift will become the dominant paradigm. (But, honestly, I hope not).

Nevertheless, I remember talking to a programmer friend about a refactoring I wanted to accomplish, and he angrily sketched out a better build system which could have solved the problem using a Turing-complete constraint language to figure out the dependencies.

I just remembered the famous quote from the creator of ANTLR - “Why program by hand in 5 days what you can spend 25 years of your life automating?” - and handwrote a script to solve the problem in an hour, and got on with my life.

-the Centaur

Pictured: Some of the older programming language books that I have in my stacks, most of which are now worse than useless for getting things done nowadays - though if you really love programming languages and learning how things work, they're more than priceless, now and forever.

[twenty twenty-four day twenty-four]: in foggiest depths

centaur 0

One of the problems with computing is when it just gets ... foggy. Not when you're trying to do something hard, or when two pieces of software are incompatible, no. When things just sort of kind of don't work, and there are no known reasons that it's happening, and no reliable actions you can take to fix it.

Once this happened to me when I was working on a robotics device driver, and I realized the lidar itself was unreliable, so the only way to fix problems was to run each configuration ten times and keep average stats. Broken "worked" around ten percent of the time, whereas "fixed" worked around seventy percent of the time (approaching the rate at which the manufacturer's own software could connect to its own hardware).

Today, I ran into a seemingly simple problem with Anaconda, a Python package / environment management system. Conda lets you corral Python and other software into "environments" with different configurations so that potentially incompatible versions can be used on the same computer (albeit, not at the same time). It even gives you a handy indication about which environment is in use in your command prompt, like so:

There's a seemingly innocent blank line between (ThatEnvironment) and the previous line, yes? Not part of the standard Conda setup, but you can easily add it with a single line of configuration, changing the "env_prompt" to include an extra newline "\n" before printing the environment, like so:

Yeah, that line at the end. "env_prompt: \n({default_env})". In a conda configuration - a .condarc, or "dot condarc" file - which is almost as simple as possible. I don't even think the "channels" bit is needed - I didn't recall writing it, I think it just got added automatically by Conda. So this is almost the simplest possible change that you could make to your Conda configuration, done in almost the simplest possible way.

Except. It. Didn't. Take.

No matter what changes I made to the .condarc file, they didn't affect my Conda configuration. Why? I don't know. No matter what I did, nothing happened. I changed the prompt to all sorts of weird things to try to see if maybe my syntax was wrong, no dice. No amount of searching through manuals or documentation or Stack Overflow helped. I re-ran conda config, re-loaded my shell, rebooted my Ubuntu instance - nothing.

Finally, almost in desperation, I went back to my original version, and tried creating system-wide, then environment-specific configurations - and then the changes to the prompt started working. Thank goodness, I thought, and rebooted one more time, convinced I had solved the problem.

Except. It. Took. The. Wrong. Config.

Remember how I said I created a weird version just to see that it was working? Conda started reverting to that file and using it, even though it was several versions ago. It actively started overwriting my changes - and ignoring the changes in the environment-specific configurations.

So, I blew away all the versions of the file - local, system and environment-specific - and re-created it, in its original location, and then it started to work right. In the end, what was the final solution?

I have no idea.

When I started working on the problem, I wanted Conda to do a thing - print an extra blank line so I could more easily see a command and its result, separate from the next command and result. And so I created a file in the recommended place with a line containing the recommended magic words ... and it didn't work. Then I hacked on it for a while, it sort of started working, and I backed out my changes, creating a file in the same recommended place with a line containing the same recommended magic words ... and it did work.

Why? Who knows! Will it keep working? Who knows! If it breaks again, how do I fix it? Who knows!

This is what I call "the fog". And it's the worst place to be when working on computers.

-the Centaur

Pictured: Sure was foggy today.

[forty-three] minus twenty-two: it gets stale

centaur 0

Recently I went to do something in Mathematica - a program I've used hundreds if not thousands of times - and found myself stumped on a simple issue related to defining functions. I've written large, complicated Mathematica notebooks, yet this thing I done hundreds of times was stymieing me.

But - yes - I'd done it hundreds of times; but not regularly in the past year or so.

My knowledge had gone stale.

Programming, it appears, is not like riding a bike.

What about other languages? I can remember LISP defun's, mostly, but would I get a C++ class definition right? I used to do that professionally, eight years ago, and have published articles on programming C++ ... but I've been writing almost exclusively Python and related scripting languages for the past 7 years.

Surprisingly, my wife and I had this happen in real life. We went to cook dinner, and surprisingly found some of the stuff in the pantry had gone stale. During the pandemic, you see, we bought ahead, since you couldn't always find things, but we consumed enough of our staples that they didn't go stale.

Not so once the rate of consumption dropped just slightly - eating out 2-3 times a week, eating out for lunch 2-3 times a week - with a slight drop in variety. Which meant the very most common staples were consumed, but some of the harder-to-find, less-frequently-used stuff went bad.

We suspect some of it may have had near-expired dates we hadn't paid attention to, but now that we're looking, we're carefully looking everywhere to make sure our staples are fresh.

Maybe, if there are skills we want to rely on, we should work to keep those skills fresh too.

Maybe we need to do more than just "sharpen the saw" (the old adage that work goes faster if you take the time to maintain your tools). Perhaps the saw needs to be pulled out once a while and honed even if you aren't sawing things regularly, or you might find that it's gone rusty while it's been stored away.

-the Centaur

Pictured: The bottom layers of detritus of the Languages Nook of the Library of Dresan, with an ancient cast-off office chair brought home from the family business by my father, over 30 years ago.

RIP Jeff Bezos (and/or Richard Branson)

centaur 0
rip jeff bezos

You know, Jeff Bezos isn’t likely to die when he flies July 20th. And Richard Branson isn’t likely to die when he takes off at 9am July 11th (tomorrow morning, as I write this). But the irresponsible race these fools have placed them in will eventually get somebody killed, as surely as Elon Musk’s attempt to build self-driving cars with cameras rather than lidar was doomed to (a) kill someone and (b) fail. It’s just, this time, I want to be caught on record saying I think this is hugely dangerous, rather than grumbling about it to my machine learning brethren.

Whether or not a spacecraft is ready to launch is not a matter of will; it’s a matter of natural fact. This is actually the same as many other business ventures: whether we’re deciding to create a multibillion-dollar battery factory or simply open a Starbucks, our determination to make it succeed has far less to do with its success than the realities of the market—and its physical situation. Either the market is there to support it, and the machinery will work, or it won’t.

But with normal business ventures, we’ve got a lot of intuition, and a lot of cushion. Even if you aren’t Elon Musk, you kind of instinctively know that you can’t build a battery factory before your engineering team has decided what kind of battery you need to build, and even if your factory goes bust, you can re-sell the land or the building. Even if you aren't Howard Schultz, you instinctively know it's smarter to build a Starbucks on a busy corner rather than the middle of nowhere, and even if your Starbucks goes under, it won't explode and take you out with it.

But if your rocket explodes, you can't re-sell the broken parts, and it might very well take you out with it. Our intuitions do not serve us well when building rockets or airships, because they're not simple things operating in human-scaled regions of physics, and we don't have a lot of cushion with rockets or self-driving cars, because they're machinery that can kill you, even if you've convinced yourself otherwise.

The reasons behind the likelihood of failure are manyfold here, and worth digging into in greater depth; but briefly, they include:

  • The Paradox of the Director's Foot, where a leader's authority over safety personnel - and their personal willingness to take on risk - ends up short-circuiting safety protocols and causing accidents. This actually happened to me personally when two directors in a row had a robot run over their foot at a demonstration, and my eagle-eyed manager recognized that both of them had stepped into the safety enclosure to question the demonstrating engineer, forcing the safety engineer to take over audience questions - and all three took their eyes off the robot. Shoe leather degradation then ensued, for both directors. (And for me too, as I recall).
  • The Inexpensive Magnesium Coffin, where a leader's aesthetic desire to have a feature - like Steve Job's desire for a magnesium case on the NeXT machines - led them to ignore feedback from engineers that the case would be much more expensive. Steve overrode his engineers ... and made the NeXT more expensive, just like they said it would, because wanting the case didn't make it cheaper. That extra cost led to the product's demise - that's why I call it a coffin. Elon Musk's insistence on using cameras rather than lidar on his self-driving cars is another Magnesium Coffin - an instance of ego and aesthetics overcoming engineering and common sense, which has already led to real deaths. I work in this precise area - teaching robots to navigate with lidar and vision - and vision-only navigation is just not going to work in the near term. (Deploy lidar and vision, and you can drop lidar within the decade with the ground-truth data you gather; try going vision alone, and you're adding another decade).
  • Egotistical Idiot's Relay Race (AKA Lord Thomson's Suicide by Airship). Finally, the biggest reason for failure is the egotistical idiot's relay race. I wanted to come up with some nice, catchy parable name to describe why the Challenger astronauts died, or why the USS Macon crashed, but the best example is a slightly older one, the R101 disaster, which is notable because the man who started the R101 airship program - Lord Thomson - also rushed the program so he could make a PR trip to India, with the consequence that the airship was certified for flight without completing its endurance and speed trials. As a result, on that trip to India - its first long distance flight - the R101 crashed, killing 48 of the 54 passengers - Lord Thomson included. Just to be crystal clear here, it's Richard Branson who moved up his schedule to beat Jeff Bezos' announced flight, so it's Sir Richard Branson who is most likely up for a Lord Thomson's Suicide Award.

I don't know if Richard Branson is going to die on his planned spaceflight tomorrow, and I don't know that Jeff Bezos is going to die on his planned flight on the 20th. I do know that both are in an Egotistical Idiot's Relay Race for even trying, and the fact that they're willing to go up themselves, rather than sending test pilots, safety engineers or paying customers, makes the problem worse, as they're vulnerable to the Paradox of the Director's Foot; and with all due respect to my entire dot-com tech-bro industry, I'd be willing to bet the way they're trying to go to space is an oversized Inexpensive Magnesium Coffin.

-the Centaur

P.S. On the other hand, when Space X opens for consumer flights, I'll happily step into one, as Musk and his team seem to be doing everything more or less right there, as opposed to Branson and Bezos.

P.P.S. Pictured: Allegedly, Jeff Bezos, quick Sharpie sketch with a little Photoshop post-processing.