Deriving kind from instance of kind

On several occasions I’ve needed constructs on the form of

To decide whether (X - a thing) is sibling to (Y - a thing): if the kind-name of X is the kind-name of Y, decide yes; decide no.

This same basic issue has come up earlier on raif, and probably elsewhere as well. The proposed solution I found, however, is I6 based and (at least in the Window 7 build of 6F95) seems to kill the compiler.

To say kind name of (x - thing): (- print (I7_Kind_Name) {x}.&i7_kind-->0; -).
The ability to test whether thing A is of a kind with B would be great, but not enough by itself. No, on more than a few occasions I’ve needed to check whether this thing derives from the kind of another thing, or even whether a particular kind name begins with “pair of…-”. The chore removing “[owner]'s” from an incorporated thing is recurring, and I’d love a more elegant way of doing it.

But it does seem inordinately difficult. Is it still possible to do something like this in recent builds? Or is it (as I’m beginning to suspect) discouraged as a bad or unsafe practice?

[size=85]EDIT: Made some clarifications.[/size]

The 6F95 version of that kind-printing hack:

To say kind name of (x - thing):
   (- print (I7_Kind_Name) KindHierarchy-->(({x}.KD_Count)*2); -).

The sort of kind operators you’re talking about can be hacked together, but obviously these internals are still changing with every release. I don’t know why they’re not built in.

Is there a difference? If Fluffy is an animal, and Steve is a person, then Fluffy derives from Steve’s kind. But it is also true that Fluffy and Steve are both people.

If you want to know whether the kind name matches a particular string, by far the easiest way would be to declare an either-or property “name-pairy” and have some kinds be usually name-pairy. You don’t need to mess around with the kind machinery for that.

Okay, this is seriously borderline embarassingly hackish, but I have in fact resorted to giving my things some text called kind (kind_name, actually). Thus, I can test whether the kind of A is the kind of B, and with a little extra work, whether the kind of A is in the same general “family kind” of B. I think the easiest way to do this with text is lists: is the kind of A and the kind of B are listed in the Person Kind List, then blah blah blah. This doesn’t give derivation, though, since I’ve never needed it to; I’ve only needed to know if the two things have been similar enough or different enough.

I think you could set this up with a table if you needed to, though:

Table of Embarassingly Hackish Kinds
“person” {“animal”, “man”, “woman”}

It’s work, and you have to be very careful to define everything and make sure you’re clear and careful about what you use it for, but it’s let me do some things that would be excruciatingly difficult otherwise. The second option is one I don’t use much, but I use the “is the noun the same sort of thing as the stuff in the container?” kind of query all over the place. I’m glad to know about the I6 option, but will probably keep working with text for awhile, because I fully understand what’s happening, and that’s more important right now than elegant code. (Also, you can easily fiddle with the text for output reasons, which is nice.) I’ll make a note to pare it down in the future, though.

The I6 option is not elegant code. :slight_smile:

Hm. I wonder if the relative opaqueness of this stuff is because Graham is planning to switch to multiple-inheritance someday. That would mess with the semantics of any kind operators.

(I am only speculating here.)

Interesting. As an aside, how does one best keep track of the particulars of such changes? Is it necessary to examine the source code, or is everything given in the I7 change log?

Crud, I knew I messed up that sentence. It should say, “on more than a few occasions, I’ve needed to be able to check whether the kind of (A) is itself kind of the kind of (B). That is, to be able to traverse the inheritance tree as needed.”

Note that if this were possible, I’d probably use this space to complain about something different. :slight_smile:

I’m sorry, I don’t think I’m following. How would doing so help in this instance?

I’m largely unfamiliar with I6, so I’d prefer not use it at all. If it allows me to sidestep having to declare a kind’s name twice when creating a kind, however (assuming we used gravel’s method to give the root kind the property kind_name), I’d be prepared to erect a small temple dedicated to I6 inclusions.

Yeah. It’s certainly a workable solution, and it was more or less the solution remaining. Laziness may have played some small part in why I chose not to do it, but mostly, it was for the reason I gave zarf above: namely that repetition of data is something I need to avoid. My ADHD means keeping track of scattered details is a nontrivial task, so I want to avoid cluttering the code with redundant constructions as much as I can.

Yeah. I don’t have ADHD, and I find this sort of stuff difficult to keep track of, especially when I step away for more than a day. Remembering to give new kinds appropriate labels upon creation is a huge pain, and I tend to really, really like to make kinds of things. It would make total sense if this were a feature rolled into Inform - even if most authors don’t use it (and I think they might if they could), it would be a godsend to all those marvelous extensions that deal with extra text and grouping and pronouns and whatnot.

Does the following not work? (Untested of course.)

To decide whether (X - a value) is sibling to (Y - a value): no.
To decide whether (X - a value of kind K) is sibling to (Y - K): yes.

Oh, that is elegant. Thank you. It certainly provides a large part of the needed functionality. Testing the phrase, I find it returns true for any two items that either derive from the exact same kind or when one of them is derived from a subkind of the first. Do you know if there’s a way to check if two items are exclusively siblings?

As an aside, I will admit that these value of kind K phrases are difficult for me to grasp. That recent addition to the manual felt pretty opaque and separate from the manual as a whole; to me, it read more like a brief summary of previously explained concepts.

Never mind, found it. I was just being sloppy.

To decide whether (X - a value) is sibling to (Y - a value): no.
To decide whether (X - a value of kind K) is sibling to (Y - a value of kind M): if K is M, yes; no.

EDIT again: apparently, this is not a workable solution. It only seems to work up to a point; as long as the items are statically defined it works just fine, but use them as variables and it either returns yes when it shouldn’t or, as in the case of this example, crashes at runtime.

To decide whether (X - a value) is sibling to (Y - a value): no.
To decide whether (X - a value of kind K) is sibling to (Y - a value of kind M): if M is K, yes; no.

A garment is a kind of thing. A tunic and some trousers are kinds of garment. The jersey is a tunic. John is wearing the pants and the jersey. 

Instead of jumping: 
	let X be the pants;
	let Y be the jersey;
	if X is sibling to Y, say "Eureka."

The Errea is a room. John is a man in the Errea.

Test me with "jump".

That K & M thing should work. I’m going to report it as a bug. Or even if it’s not supposed to work, the runtime error about an inability to repeat through things is off-base.