name of value of kind K

A recent thread has got me thinking it would be nice to have an “enumerating anonymous things” extension. I almost feel like I could write it, but I’m missing a couple pieces.

First, it would be nice to identify what things are anonymous. Is there any built-in way of figuring this out? The Index shows anonymous objects as “nameless,” but I can’t seem to get at the nameless/anonymous quality within the code.

Maybe it would be better to loop over all objects in scope and check if there are any duplicate names? Then things that weren’t truly anonymous but were indistinguishable by name could still be identified.

Second, I think I need to identify the most specific kind of a thing and use it as a variable. I can certainly receive it as a parameter using the (name of value of kind K) construct, but I can’t seem to come up with a syntax to indicate “name of value of kind of X”.

I think if I had those two pieces, I could write the extension.

No, there’s no way (in the compiled game) to distinguish or iterate over anonymous objects. The best you can do is reserve a kind solely for anonymous objects, and iterate over that kind.

The way to extract the (most specific) kind of an object, as I noted in another thread, is:

 KindHierarchy-->(({x}.KD_Count)*2); 

But this may change in future I7 releases, as it has changed in past ones.

Or reserve a property, right, which would allow you to keep a hierarchy of kinds…? Or is there an implicit part of the logic required by capmikee’s proposed extension that I’m missing?

–Erik

For now I’m going with things that have non-unique names, instead of meddling with kinds. But I’ve run into another snag:

[spoiler][code]Graveyard is a room.

A monster is a kind of person. Understand “monster” as a monster.

A zombie is a kind of monster.
A skeleton is a kind of monster.

There are four zombies in graveyard.
There are two skeletons in graveyard.

Ordinal is a kind of value. The ordinals are unordered, first, second, third, fourth.
A thing has an ordinal called order. Understand the order property as describing a thing.

Definition: a thing is unique rather than non-specific if it is a last named item listed in Table of Non-Specific Names and the order of it is first.

Before printing the name of a non-specific thing:
say "[order] "

After reading a command:
repeat through Table of Non-Specific Names:
say “deleting row [non-specific name entry]/[last named item entry].”;
blank out the whole row;
repeat with candidate running through things in the location:
unless we updated a non-specific name row for candidate:
say “creating row from [printed name of candidate].”;
now the order of candidate is first;
Choose a blank row in Table of Non-Specific Names;
now the non-specific name entry is the printed name of candidate;
now the last named item entry is candidate;

To decide whether we updated a non-specific name row for (candidate - an object):
Repeat through Table of Non-Specific Names:
say “entry: [non-specific name entry] printed name: [printed name of candidate].”;
if non-specific name entry is the printed name of candidate:
say “found row matching [printed name of candidate].”;
now the order of candidate is the ordinal after the order of the last named item entry;
now the last named item entry is candidate;
decide yes;
decide no;

Table of Non-Specific Names
non-specific name last named item
a text an object
with 20 blank rows

Check an actor attacking something that is not a monster (this is the only attack monsters rule):
stop the action with library message attacking action number 1 for the noun.

The only attack monsters rule is listed instead of the block attacking rule in the check attacking rulebook.

Report attacking something:
Say “You hit [the noun] with a mighty blow!”

test me with “attack monster/first/zombie”
[/code][/spoiler]

Since “listed in” wasn’t working, I tried manually looping over the Table of Non-Specific Names. But as the debugging statements show, the printed name never matches the non-specific name entry at all. As far as I can tell, they’re both texts, and they’re sometimes the same, and yet the code to update the row instead of creating a new one never runs. What am I doing wrong?

It seems you will get a match if you make the non-specific name entry indexed text instead.

That can’t be the only way.

The entries will also match if you explicitly give monsters printed names. (I mean like ‘The printed name of a zombie is usually “zombie”.’)

The printed name property is text; but what type is the name one uses when originally defining the object in source text? (I mean like ‘zombie’ in “A zombie is in the Graveyard.”)
Obviously, one can tell Inform to say the printed name of objects one never bothered to actually give an explicit printed name, and it will say the name that the object has in the source text instead.

[Edit: Erasing patently wrong suggestions.]

And obviously, telling Inform to put the printed name of the monsters in the non-specific names column will put their source text names there for want of an explicitly set printed name. (So I suppose that is text, too.)

But it seems that yet a test whether the source text name in the non-specific name entry is the printed name of a monster fails …

That seems reasonable, but how do you explain this?

now the non-specific name entry is the printed name of candidate;
The assignment gives the non-specific name entry a value of “zombie.” Is it unreasonable to expect a comparison to work in a place where an assignment already works?

And if it really truly will not ever work, is there some sneaky way of using that to test if an object is anonymous? Perhaps something like:

Definition: A thing is anonymous if: Let T be a text; Let T be the printed name of X; Decide on whether or not T is not the printed name of X.

Of course it’s a perfectly reasonable expectation! It’s a mystery to me why it doesn’t work. Perhaps it has something to do with the I6 print routines?

Apparently it’s an ill wind that blows nobody any good!

Nope, that doesn’t work:

[code]Definition: A thing (called candidate) is explicitly named rather than anonymous:
choose row 1 in Table of Non-Specific Names;
Now the non-specific name entry is the printed name;
Now the last named item entry is candidate;
Decide on whether or not non-specific name entry is the printed name.

When play begins:
Repeat with item running through things:
say “[The item] is [if item is not anonymous]not [end if]anonymous.”;
[/code]

I get this:

I’m guessing that the printed name of an anonymous thing matches itself as a text, but not the printed name of another anonymous thing. Why would that be?

Okay, let’s try another tack. These printed names match:

Quisling1 is a person in graveyard. The printed name of quisling1 is "zombie". Quisling2 is a person in graveyard. The printed name of quisling2 is "zombie".

Adding that produces this rather odd output:

Which makes me think that Inform has some potentially useful code for handling items of the same kind. Is it buried deep in I6?

The default printed name thing is definitely a bug. When the printed name of an object is autogenerated (either from its own name, or anonymously from the class name) you get a duplicate I6 string object, which fails matching tests. (I6 strings are not interned; I7 strings usually are, but not in this case.)

I’ll file it.

Simple test case:

The Kitchen is a room.

The rock is a thing in the Kitchen.
The stone is a thing in the Kitchen. The printed name is "stone".

When play begins:
	if the printed name of the rock is "rock":
		say "Rock: match.";
	if the printed name of the stone is "stone":
		say "Stone: match.";

Good to know. I would be willing to use indexed text on a temporary basis until this is fixed, but my curiosity has been piqued once again regarding grouping objects of like kind. Do you think it would be possible to use some of that code to generate ordinal identifiers for grouped items?