Workaround for lazy evaluation of I7 text substitutions?

I just realized that a number of related problems I’ve been having stem from Inform’s evaluating texts lazily. Room names act strangely when they’re reported from another room, and I realized it’s because their names, which have text substitutions, are not “sticky”, but are re-evaluated from the room you’re in. Example:

Report going down when location is a passage: now the printed name of the location is "Passage from [the room up from the location] to [the room down from the location]".

When you go down to this room, the name is reported within it as Passage from Foo1 to Foo2, where Foo1 is the room up from the passage, and Foo2 is the room down from the passage.

When you go down to Foo2, however, the name of the passage is reported there as Passage from Passage from Passage from Passage from Passage from Passage from Passage from Passage from [stack overflow]. This is because “[location]” is suddenly interpreted as Foo2, so “[the room up from the location]” returns the passage itself.

Does anyone have any ideas for working around this lazy evaluation behavior? I’ve thought of using indexed texts or storing names in tables, but I’m fairly new to Inform 7, and this is the hairiest problem I’ve faced.


Ha! It just came to me.

This fixed my problem:

[code]A passage is a kind of room.
A passage has an indexed text called the sticky name.

Report going down when location is a passage:
now the sticky name of the location is “Passage from [the room up from the location] to [the room down from the location]”;
now the printed name of the location is “[the sticky name]”.[/code]

Hope this helps someone else!

Yeah, sparked by your post I had tried googling a bit for how to force a strict evaluation but came up empty. Looks like you found the way. Thanks I’m certain this will come in handy.

If you want a cleaner solution without extra variables you can just use “Passage from [the room up from the item described] to [the room down from the item described]”.

Thanks very much, Juhana! I may refactor my code later, but it’s finally working and right now I want to let it be. However, I will certainly read up on “the item described”, which doubtless has a number of uses.

It took me a while to figure this out. Eventually I realized that lazy evaluation makes sense, since a “text” is either an immutable string or a procedure that prints immutable strings. The problem comes when printing the name of a room that is not the current location. I guess you already figured it out, but if anyone looks at your code, they may find it as confusing as I did.

I tried a few experiments with this situation and it just made my brain hurt.

A way to do this without indexed text: rather than trying to change the text property, change properties that it depends on. For example, you could have

A passage has a room called the passage-source. A passage has a room called the passage-dest.
The printed name of a passage is usually “[Passage-source] to [passage-dest]”.

Then you could change a given passage’s passage-source and passage-dest at any time, and the lazy evaluation would work for you.

Ah, I got your email Ron and will add a note somewhere. This problem also crops up a lot with table entries in text.

Is this the same issue as the parameter-passing confusion you’d hit earlier?

After experimenting with something just like this, I realized that having two Passages connected to each other produces an infinite loop much like the one in the original post. (I’m assuming that Foo2 is also a passage, because if it isn’t, the original source works perfectly well for me.)

True. You could work around that in a few ways. For example, define a “say short printed name” function which defaults to the print name, but just prints “Passage” for a passage.

Yow! was supposed to tell me whenever someone replied to my post! It did work the first couple of times…

OK, from the top:

Laroquod, glad I could help somewhat. Hope you’re reading all these other clever answers.

zarf, very nice! I’ll keep this technique in mind. In this case, it doesn’t work so well, because I’m using the Exit Listings extension and I rename the passage as Foo1 when seen from Foo2 and vice versa, so that you see more helpful exit listings like “down to Foo2” and not “down to Passage from Foo1 to Foo2”.

Ron, thanks. This is not the same as the parameter problem I was experiencing. That involved an intermittent compiler error to the effect that local variables and function parameters are too ephemeral to be used in texts within the function.

capmikee, passages in my game do not connect to passages. They alternate everywhere with “beads”, like beads on a necklace’s string.

Thanks, all!