I6 feature proposal: "Dynamic string" aliases

The current functionality for dynamic strings (aka “printing-variables” per DM4) requires the use of numeric codes such as @01 to refer to them. This is a potentially useful feature, but numbers all look the same when reading code.

How about a directive that would allow these to be referred to in strings by an alphanumeric designation?

Something along the lines of:

DynamicStringAlias 01 SIDEKICK;

would alert the compiler to the binding and cause it to treat the presence of @SIDEKICK in a string just as if @01 had been used.

Note that this is different from the current string statement, which assigns strings to the numbered slots for dynamic strings at run-time. Both the directive and statement would be used, and ideally the string statement would also accept the alias. In hypothetical example:

DynamicStringAlias 01 SIDEKICK;
...
if (player has female)
    string SIDEKICK "Tiffany";
else
    string SIDEKICK "Trent";
...
Object sidekick "@SIDEKICK"
    with    orders [;
                ...
                NotUnderstood:
                    "@SIDEKICK ruminates for a while, then responds with a savvy question: ~Huh?~";
            ],
            ...
4 Likes

Plausible, but that syntax won’t work.

The list of @ escapes in text is fairly goofy these days. Comment from text.c:

	(printing only)
	@@decimalnumber  :  write this ZSCII char (0 to 1023)
	@twodigits       :  write the abbreviation string with this
						decimal number

	(any string context)
	@accentcode      :  this accented character: e.g.,
							for @'e write an E-acute
	@{...}           :  this Unicode char (in hex)              */

So "@th" already has a meaning. If you defined thing as an alias, "@thing" would be ambiguous. Never mind what happens if you define both this and thistle as aliases.

I guess "@[this]" or "@(this)" is workable. (The closing delimiter avoids the this / thistle problem.)

As for the string statement, there’s a problem there too, because this is legal:

foo = 5;
string foo "hello";

That is, you can’t just assume that a symbol argument is an alias. It could be any expression.

I think it’s okay if the stringalias directive defines a regular symbol – that is, SIDEKICK is simply a numeric constant with value 1. I’d have to think if that causes further problems, though.

But if it’s a regular numeric constant, why do we need a special category of aliases at all? We could just parse “@(SYMBOL)” and accept any constant symbol there. Then we don’t need a new directive at all; it would just be

Constant SIDEKICK = 1;

Although it would be nice to be able to set the variable value at compile time, I suppose…

See, this is not a simple request.

(It also kicks open the question of whether there can be more than 100 dynamic string variables.)

So, interestingly, it seems that part of the essence of what I’m asking about is already possible in terms of assigning a numeric value to the alphanumeric alias – as you point out it can just be a constant, which can already be used in a string statement.

It looks like the part that I thought was the easier part is the harder part, i.e. the compiler recognizing and interpreting the escape sequence inside a string. Note that I’m in no way wedded to the "@SIDEKICK" syntax – it just seemed in keeping with the style already in use. The alternates that you suggested would be fine. Even an ugly "@@@SIDEKICK" (or some other escape characters entirely) would be an improvement in readability and usability over the number codes, to me.

I would think that the limit for dynamic strings would stay the same as at present, especially since that limit was recently made expandable. And it seems reasonable to put the burden on the author for making sure that the number values used are legitimate given the configuration chosen, e.g. 0-31 as the default range.

It’s only expandable to 100, even in Glulx, because you refer to them as @00 to @99. If you can use symbols, that decision has to be reconsidered.

I have been considering this, but I don’t think I’m understanding. Are you implying that because there are an open-ended number of alphanumeric symbols the functionality would require supporting an open-ended number of dynamic strings? Wouldn’t it just be a matter of checking whether the symbol used binds to a number that would be legal for a dynamic string?

Constant SIDEKICK = 1000;

string SIDEKICK "Test"; ! would generate a compiler error

print "@(SIDEKICK) stands nearby."; ! would generate a compiler error

I see from some testing that Inform 6.31 and 6.33 don’t complain about a string statement with an assignment out of range (it seems that @loadw and @storew instructions are compiled from it), but 6.35 introduces:

Error:  Z-machine dynamic strings are limited to 96

which seems informative enough for the purpose in either case.

This got implemented a couple of months ago: Extended dynamic-string syntax by erkyrath · Pull Request #167 · DavidKinder/Inform6 · GitHub

See the I6 Addendum doc for the current state of affairs:

https://inform-fiction.org/manual/I6-Addendum.html#dynamic-strings

2 Likes

Great! Thank you.