Understanding Objects

I still struggle with objects in I7, and since this seems to be the bread and butter for creating new things in the world, I’d like to ask some questions here (after trying out things, after reading the documentation). My lack in OOPL experience is probably the reason why I struggle so much.

The term “class” is not used in I7, but I don’t know how to refer to “kind of” things otherwise, so apologies here, if I don’t stick to the right terminology.

Question number one would be if classes can refer to other classes.
I know that relations define ‘pointers’ between objects, but is it possible to do this on class level? I think the answer is “yes” as this chapter of the documentation tells me.

However, using something like:

nightwear is a kind of wearable thing. pockets are a kind of container. all nightwear have pockets.

produces an error - it seems that pockets are seen as property, but I am using the possession relation here from the standard rules (The verb to have means the possession relation.), so shouldn’t that tell I7 that this is not a property, but another class I am referring to?

Otherwise I find it difficult to deal with kind of value. That is again an object, but how do I specify better the ‘type of the value’?

To make it more concrete, I was trying to define a date. I know there is an extension for including dates of the real world into a game, but I’m not really interested in a real date. Looking at my code, I can already see that many things must be wrong or missing, I simply find it difficult to put my finger on exactly what:

A date is a kind of value.
A month is a kind of value.
A year is a kind of value.
A day is a kind of value.
A date has a day. A date has a month. A date has a year.

Current date is a date.
The day of current date is 4.
The month of current date is 5.
The year of current date is 2021.

You were close. This works:

a nightwear is a kind of wearable thing.
a pocket is a kind of container.
a pocket is part of every nightwear.

Have a look at 4.15 in the docs ‘Assemblies and body parts.’ Here you’re constructing an assembly, a type of wearable thing called a nightwear, part of which is a pocket.

If you say ‘A has a B’ as you tried, Inform is looking for B to be a value, or kind of value, not part of an assembly.

In your second example, you say ‘A day is a kind of value’. But what kind of value is it? Inform needs to know before you assign this value to things. Creating a kind of value is only necessary when you want to make your own set of possible values. e.g.

A day is a kind of value.
The days are Monday, Tuesday, Wednesday.

(see docs 8.1 Change of values that vary)

But the rest of your code indicates you don’t want that; you want the day to be a number. And numbers are a kind of value that already exist in Inform.

Now my coming example is possibly not fully what you want – or it might be – but let’s start simple. You don’t need to build a date kind the way you’re trying to build it now. If the date you’re going to be tracking is always the current date, you can create a few global variables:

The current day is initially 4.
The current month is initially 5.
The current year is initially 2021.

Then you can retrieve them when desired with a say statement:

say "The date is [current day] - [current month] - [current year].";

and manipulate them mathematically in the interim.

One step further would be to create date as a kind of thing, then assign it numeric values. This allows you to have multiple dates, each with its own name and values. This is still really involving only one new class/value: the date itself.

A date is a kind of thing.
A date has a number called the day.
A date has a number called the month.
A date has a number called the year.

current-date is a date.
The day of current-date is 4.
The month of current-date is 5.
The year of current-date is 2021.

future-date is a date.
The day of future-date is 8.
The month of future-date is 9.
The year of future-date is 2025.

In this example I created dates as a kind of thing, then specified the needed values for two dates that I also created. This would be a tedious way to create a lot of dates. Using a table to build/track them might be better, but the point here is just to show a way you can create a kind (class) of thing called a date.

-Wade

5 Likes

Thank you wade!

So there is a difference saying pockets are and saying a pocket is ?
Is are allowed at all here? Would it introduce something else?
I checked this Cheat Sheet, but that didn‘t really help.

What if I want to have two pockets as part of the nightwear?
And is there a way ‚follow‘ the part of relation?

Sorry for all these questions…

For data structure kinds, I like to do this:

An abstract object is a kind of object.
Date [ or whatever data structure ] is a kind of abstract object.

That eliminates any (unlikely but plausible) problems arising from the properties and such it would inherit as a thing, and the (more plausible) chance of running into problems because it gets matched when I’m looping through things and forgot to exclude it.

(One might wonder why not just say Date is a kind of object.? And the answer is… because then Date would be a thing. I7 doesn’t want us to make instances of the object kind, only descendants of the object kind, defaulting to thing.)

This doesn’t seem quite right?

Writing Date is an object does indeed create a thing called ‘Date’, but writing Date is a kind of object as one would expect creates a kind of object that is not a thing, according to the Kinds index, and instances of this kind can be created which are dates, not things…

Yeah, I managed to confuse myself. If you say Today is a kind of object. Today would be a thing. If you say Date is a kind of object. Today is a date. then Today is not a thing. The abstract object dodge is only relevant for making instances and redundant if you’re making a subkind. Never mind. :roll_eyes:

Heh, I probably made it a single pocket subconsciously to make things easier for myself while writing the demonstration :slight_smile:

When creating physical objects, you have to think about whether you want them to be single-named or plural-named, and what indefinite article you want them to have. I actually wrote a post about this in response to another question a week ago (Uncountable nouns - #2 by severedhand) ‘is/are’ on its own won’t make a difference, but the word before pockets will. ‘some pockets’ will create a plural-named objects, ‘a pocket’ will create a singular-named.

It’s usually best to think about the single/plural issue practically (for programming) rather than realistically. What I mean is, sure, a nightwear in real life probably has a couple of pockets. But do you want the player to actually have to specify which of two pockets they put things into? That would make for complex disambiguation, and annoyance for the player.

So the workaround here may be to create a single container in the nightwear, but we’ll call it ‘pockets’ and make it plural-named. And we’ll also let the player refer to it as ‘pocket’ (singular), even though behind-the-scenes it is plural-named. Here’s the demo of this stuff:

Lab is a room.

a carrot is in lab.

a nightwear is a kind of wearable thing.
the gown is a nightwear. player wears the gown.

some pockets are a kind of container.
pockets are a part of every nightwear.
Understand "pocket" as pockets.

Test me with "get carrot/put carrot in pocket/x pockets/get carrot".

So you could have two separate pockets, but this way is much easier for player and programmer.

Sorry, I don’t understand this question?

-Wade

2 Likes

Still don’t get this. If you write Today is a kind of object. then there is not (yet) any instantiation of objects (or things) but there is a new kind created, a sub-kind of objects, called ‘Today’. Any instantiation subsequently created of ‘Today’, such as Current-date is a Today. will be an object of (sub)kind ‘Today’, but not of (sub)kind ‘thing’…

And that’s because I’m a king doof who shouldn’t have been allowed near a keyboard today and I meant to say Today is an object.

So, unless I’m still missing something, it seems to me that you can simply write Date is a kind of object to create a data structure kind without requiring an intermediary ‘abstract object’ kind?

yup, that’s what I was trying to express in my previous correction where I introduced a different error.

If you look to WI 13.13 you’ll see the phrases that let you follow relations in general.

Thanks wade!

Now I’d like to come back to my original question using your code.
So in your solution some pockets are a kind of container and pockets are a part of every nightwear, so we relate the kind (class) pockets to the kind (class) nightwear. When we instantiate the gown, I7 also creates an instance of pockets I assume.

So far so good. Now I’ll add @Zed 's code from here, to achieve that the contents of the pockets are shown in the inventory:

Lab is a room.

a carrot is in lab.

a nightwear is a kind of wearable thing.
the gown is a nightwear. player wears the gown.

some pockets are a kind of container.
pockets are a part of every nightwear.
Understand "pocket" as pockets.

Use the serial comma.

Rule for printing inventory details of gown:
  say " (the pockets ";
  if the first thing held by the pockets is nothing begin;
    say "is empty";
  else;
    say "contain ";
    list the contents of the pockets, as a sentence, giving brief inventory information, tersely, not listing concealed items;
  end if;
  say ")";

Test me with "get carrot/put carrot in pocket/ inventory / x pockets/get carrot".

I7 seems to complain about pockets not being an object (maybe because in its definition it is actually a kind ? ):

Problem. You wrote 'if the first thing held by the pockets is nothing'  , but 'pockets' is used in a context where I'd expect to see a (single) specific example of an object, not a description.

I made it work in the end by defining nightwear-pockets as kind first, and then creating an instance with some pockets are nightwear-pockets, but I wonder if there is another way to help I7 understand that in Zed’s rule, we’d like to refer to the instantiated object of pockets (what would be its name?), not the kind definition. Any ideas?

Thank you all for looking into this! And @zed, don’t put your keyboard away, because your suggestion was actually what I had in mind (creating structure type for Date).

Maybe someone said it already somewhere, but I believe there are not methods for objects in I7? I mean functions (phrases) that would only apply to Date? You would probably just say something like:
To add a day to (D - a Date): ....

Otherwise, I found this page really helpful as a cheat sheet, just to look up how to put it down in I7:
https://learnxinyminutes.com/docs/inform7/

That page alone will not help, but when you know the basics already, it can be helpful.
Thanks for filling these gaps!

1 Like

They’re not methods, but it’s possible for objects to have properties that are phrases. @drpeterbatesuk gave an example of using phrase properties in a kinda sorta method-ish way… but they’re sufficiently clunky to use that you may be hard-pressed to find an application for them where there isn’t a simpler alternative.

Exactly; that is a phrase which applies only to Date.

The reason Zed’s code isn’t working here is because it has only one pocket; a single container called pocket. So in that code, whenever he says ‘pocket’, Inform knows exactly what thing he’s talking about.

In the lab/carrot version, we’ve created a whole kind called ‘pockets’. When we refer to ‘pockets’ in the source in this situation, we’re talking about the kind, not any specific pocket. We can say ‘the gown’s pockets’ to address the gown’s pockets, but we want the inventory command to work on any nightwear, not just the gown. To that effect, I’ve added a second nightwear to this example, the pyjamas, with a toothbrush in their pocket:

Lab is a room.

a carrot is in lab.

a nightwear is a kind of wearable thing.

some pockets are a kind of container.
pockets are a part of every nightwear.
Understand "pocket" as pockets.

the gown is a nightwear. player wears the gown.

the pyjamas are a nightwear.
the pyjamas's pockets contain a toothbrush.
player wears pyjamas.

Use the serial comma.

Rule for printing inventory details of a nightwear (called NIGHTY):
	let THIS-POCKET be a random pockets enclosed by NIGHTY;
	say " (the pockets ";
	if the first thing held by THIS-POCKET is nothing begin;
		say "are empty";
	else;
		say "contain ";
	list the contents of THIS-POCKET, as a sentence, giving brief inventory information, tersely, not listing concealed items;
	end if;
	say ")";

Test me with "get carrot/put carrot in pocket/gown's pockets/inventory/x gown's pockets/x pyjamas's pockets".

The inventory rule now fires twice, once for the pyjamas and once for the gown. Each time, it identifies the particular nightwear it’s looking at as NIGHTY, and then, the pocket of that nightwear as THIS-POCKET. The line that identifies THIS-POCKET is a bit yucky (let THIS-POCKET be a random pockets enclosed by NIGHTY;) but that’s the usual way to identify the one thing you want in these circumstances. We know a nightwear has only one pockets, so randomly picking one will pick the one we want.

The test now also shows how annoying it can be to have more than one pockets around :slight_smile: We have to type things like ‘pyjamas’s pockets’ or be asked a question about the pockets each time.

Keep reading 4.15. It actually has a jacket-with-pockets example that’s similar to what we’ve done here.

PS - There’s nothing magical about the all-caps and hyphens of THIS-POCKET, etc. That’s just my personal style for giving names to temporary variables.

-Wade

2 Likes

Thanks Wade!

I never would have been able to come up with the line that identifies THIS-POCKET. :face_with_raised_eyebrow: :grinning_face_with_smiling_eyes:

1 Like