Sure thing! I am honored to receive this suspiciously bubbling beaker!
So, Inform has a very elaborate system for printing lists of objects. This is accessed through a phrase with a truly staggering number of options:
To list the contents of (something - an object), with newlines, indented, as a sentence, including contents, including all contents, giving inventory information, giving brief inventory information, using the definite article, listing marked items only, prefacing with is/are, not listing concealed items, suppressing all articles and/or with extra indentation:
Why are all these options necessary? Well, in Inform, descriptions like “angry male people in the Gymnasium” are values in their own right, which we can pass around to phrases as much as we like! So it’s very easy for an author to specify what things should be in their list.
The hard part is specifying what should be printed for each item in the list. That’s why we need options like “suppressing all articles” and “using the definite article”. This is also the difficult part for printing lists of anything that’s not an object.
The solution to this problem came from the Hadean Lands source, where zarf used a text for this! His list-writer sticks the current item into a global variable called “substitution-variable”, and the text you pass into the list-writer can thus reference “[the color of the substitution-variable]” or whatever you like.
Previously, I’d been writing my own little mini-list-writer code every time I needed a customized list. For example, I have a “to (direction)” phrase to handle the difference between “to the north” and “upward” (or, in this particular case, “to starboard” and “forward”!). If I want to say “You can go…” followed by a list of viable directions, using this phrase, I need to write my own loop that prints all the commas in the right places and everything. Or, I have a kind of value called “position”, which has a property called “name” (to handle the fact that “above” already has a meaning to I7). If I want to print a list of positions using their names, again, I need to handle all the commas and “ands” myself.
But with this text trick, suddenly that’s no longer needed!
First, a hack that I’ve used before to access activity parameters. In I6, variables don’t have types. In I7, they do. But in I7, you can pass kind names to phrases! So:
To decide which K is the (name of kind of value K) being listed: (- listing_parameter -).
To set the (name of kind of value K) being listed to (V - K): (- listing_parameter = {V}; -).
So now we have a variable, the “thing being listed” (or “direction being listed” or “position being listed” or “number being listed” or…), which can take on any type we want it to. Sorry, type-checker.
Then, we take in a description and a text:
To print a list of (T - text) for (D - description of values of kind K), prefacing with is/are and/or disjunctive:
Note that “description of values of kind K”. Inform’s type-checker knows that “viable directions” is a description of directions, and “positions accepted by the noun” is a description of positions. So there’s no need for the author to specify that explicitly: Inform tells our phrase what its type-checker knows already!
There are two main things we can do with descriptions, and we’re going to do both:
let N be the number of D;
Find out how many there are, and…
repeat with V running through D:
set the K being listed to V;
say T;
…repeat through them!
The rest is just a bunch of details to get commas in the right places and handle nested lists (instead of clobbering the listing-parameter variable, we push it onto the stack, and pull it back when we’re done). But we can now say:
print a list of “[to the direction being listed]” for viable directions
print a list of “[name of the position being listed]” for positions accepted by the noun
Or anything else, for that matter! Using texts referencing a global variable like this really is a game-changer!