This is about the perils of migrating from one programming language to another. Probably all programmers who are more experienced than I at using multiple languages (which would be most programmers, I’m sure) have run into this type of problem, but it’s a new one for me. It only took me half an hour of commenting out blocks of code to find it, and it’s a good one.

I’ve used TADS 3 extensively, and more recently than I’ve used Inform 6. So it’s all too easy to type a T3 statement out of habit rather than use the I6 equivalent. Some of these mistakes will produce warning or error messages from the compiler. But this one doesn’t:

if (self.location == sandy_beach)

That’s correct T3 (although no ‘self’ is required), but it’s disastrous I6. The correct I6 statement is:

if (self in sandy_beach)

The bad code compiles in I6 (arguably it shouldn’t, because no object has a location property to reference), but when the program attempts to evaluate that line at run-time, wacky things happen. The run-time error message doesn’t correctly identify the problem. Instead, it complains that the object doesn’t have a random property that couldn’t possibly be referenced in that object, because there’s no code that will ever attempt to call that property on that object.

On the other hand, as Khelwood explained to me on the newsgroup, I6 lets you store a property ID in a global variable. In rare situations — so rare that I can’t even imagine one — this might be a useful thing to do. if I set my_global to be the value of this_obj.this_prop, then I can call this_obj.my_global and get the expected result, which is that the call will actually go to this_obj.this_prop. So the only weakness of the compiler is that it doesn’t recognize location as a global variable that’s already being used by the library, and therefore shouldn’t be used in this manner.

You could make a good case that the compiler shouldn’t treat globals defined by the library any differently than it treats globals defined by the user. So this isn’t actually a problem with the compiler — it’s just a frayed edge, a place where I6 isn’t tightly woven.

This is my second experience with weird run-time problems in I6. The first time was also due to a TADS habit. I used a single-quoted string as a property of an object, when a double-quoted string was called for (as it always is in I6, except when you’re constructing the name array). Again, the compiler was happy, but the game reacted very badly when that property was referenced, repeating a longish chunk of output text like a babbling idiot.

This is all a little scary, because it’s entirely possible that I’m perpetrating other bad stuff in my code that hasn’t popped up yet.

Advertisements

One thought on “A Little Knowledge

  1. Well, for all its historical merits, the Z-Machine is a very quirky platform, and I6 has inherited that quirkiness. (Don’t take that as a criticism, MU* engines are much worse in this regard.) I’d probably have the same problems switching from I6 to TADS3, and that’s after 11 years of professional programming experience with half a dozen languages used frequently and at least as many occasionally. Just chalk it up to experience, and thanks for the warning!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s