I7: Expanded compiler type deduction possible?

The I7 compiler is able to deduce the kind of something previously unmentioned when it is involved in a relation. The following causes no issues:

A race car is a kind of vehicle.

Driving relates one person (called the driver) to various race cars. [compiler informed of required kinds]

The Speedster is driven by Mr Speedy. [deduces kinds for both Speedster and Speedy]

However, the compiler is not able to deduce the kind of something previously-unmentioned when it is assigned as a property. The last statement of the following triggers a Problem message:

A race car is a kind of vehicle.

A race car has a person called the driver. [compiler informed of required kind]

The Speedster is a race car. The driver of the Speedster is Mr Speedy. [can't deduce that Speedy is a person]

The Problem message resulting seems like the compiler is trying to make a deduction about Mr Speedy but is getting no farther than deciding it must be an object.

Problem. In the sentence ‘The driver of the Speedster is Mr Speedy’ , it looks as if you intend ‘The driver of the Speedster is Mr Speedy’ to be asserting something, but that tries to set the value of the ‘driver’ property to an object - which must be wrong because this property has to be a person.

Type information is available to the compiler – the Problem message even indicates an awareness of the required type! Why doesn’t it make the same kind of deduction as it does for relations? Is this something that could be implemented?

4 Likes

submitted as feature request I7-2377.

1 Like

Thinking back on this in the light of this comment in another thread:

I had a couple typos in the region and/or backdrop names. Interestingly, I did not get a parser error. It went merrily on and just didn’t work correctly.

A perennial win/lose of Inform is that if you make a typo in an assertion, it cheerfully creates an almost-duplicate object.

The Living Room is west of the Kitchen.
The evlish sword is in the Lviving Room.

You generally have to type TREE to figure out what’s wrong, and most authors won’t think of that.

Whereas if there’s a typo in the above example, the compiler reports it as an error:

A race car has a person called the driver. 
Mr Speedy is a person.
The Speedster is a race car. The driver of the Speedster is Mr Speody. 

Problem. In the sentence ‘The driver of the Speedster is Mr Speody’ , it looks as if you intend ‘The driver of the Speedster is Mr Speody’ to be asserting something, but that tries to set the value of the ‘driver’ property to an object - which must be wrong because this property has to be a person.

Okay, it’s not the most transparent error, but it’s a better outcome than creating a second person object named “Mr Speody”.

I’m not saying this is better or worse. But it is clearly making life easier for one author at the expense of making it harder for another. It’s impossible for the compiler to get both cases right, because the difference between a typo and an intended object exists only in the author’s head.

So if you add this sort of inference to any kind of statement, or remove this kind of inference, you’re making a tradeoff.

(I believe that in any case where Inform is willing to infer the kind of an object, it is also willing to infer the existence of the object. That is, you can’t make it smarter about types without also setting up a created-a-typo-object loophole. But I may be wrong about this!)

2 Likes

It’s the nature of power that it can be misapplied. There’s value in consistency, even if that consistency requires consistent care in writing code. As you point out, Inform already has a class of functionality that fails to protect against typos (which would be a technical impossibility, anyway); I don’t think that this would make the situation substantially worse for anyone being bitten by them.

It would make sense to add a separate feature to turn off object existence inference, though, such that only object-creating assertions can create new objects. It would be a user-selected limitation similar to the “use full names of objects only” option.

5 Likes

I would use this 100% of the time (I use Use unabbreviated object names. all the time, too). The only time I ever use the “infer existence” thing on purpose is with rooms, and I’ll happily type The camp is a room. The camp is west of the waterfall. if it means I never end up with another blal (ball)!

1 Like

I agree this would be a good feature, but the argument over “what is an object-creating assertion” is going to go on a while. :)

2 Likes

This feature also makes for really misleading error reports (at least for those of us who don’t read them closely enough).

The incredible bouncy ball is a thing. The incredible bouncy ball can be squashed or unsquashed. it is unsquashed.

Instead of throwing the incredible bouncy ball:
	say "The ball splats against the wall. It wasn't very bouncy.".
	now incredible bouncy ball is squashed.

Gives

Problem.  You wrote 'Now the incredible bouncy ball is squashed'  (line 9): but the property squashed for the now incredible bouncy ball is not allowed to exist, because you haven't said it is. What properties something can have depends on what kind of thing it is: see the Index for details.

Because it’s trying to make a new “now incredible bouncy ball” which doesn’t have the property defined. But I always spend a few minutes trying to work out if I’ve screwed up the property or accidentally used an existing one in an incompatible way or something.

Really, I’ve misplaced a full stop, but you’d never know it from the error.

1 Like

I wasn’t being very clear, but by “object-creating assertions” (which I probably should have called object-creation assertions), I meant the most basic assertions of object existence like:

The Barn is a room.
A bucket is in The Barn. [*]
A hole is part of the bucket. [*]
A pebble is in the bucket. [*]

A cow is a kind of female animal.
Bessie and MooMoo are cows in the Barn. [*]

There is a man called the farmer.

… which I think actually includes several examples of asserting existence via relations (the starred ones, which I think is your point).

I guess with the theoretical use option set, it would have to be:

The Barn is a room.
There is a bucket. The bucket is in The Barn.
There is a hole. It is part of the bucket. [pronouns are helpful]
There is a pebble. The pebble is contained by the bucket. [alternative relation verbs may also be helpful]

A cow is a kind of female animal.
Bessie and MooMoo are cows.
Bessie and MooMoo are in The Barn.

There is a man called the farmer.

This is extremely hard in general, and you can’t really blame the object-creation feature. Imagine that the compiler didn’t infer the creation of an object, in your example. What would the error message look like then? Probably

You wrote ‘Now the incredible bouncy ball is squashed’ (line 9): but no object named “now the incredible bouncy ball” exists.

This is equally unhelpful! Now you spend the same few minutes looking for where you created the object; the erroneous full stop is still off the radar.

(I am reminded of the legend about the SAIL programming language of the 1970s, in which – at some early stage – the only error message was “THIS IS NOT A SAIL PROGRAM”.)

2 Likes

Yeah. We all have habitual idioms for “this is how I create Inform objects”, but they vary somewhat between authors.

I would accept any assertion that mentions a kind as legitimately asserting existence.

The Kitchen is a room.
The coin is a thing.
The rock is a thing in the Kitchen.
The window is a scenery thing in the Kitchen.
A thing called the stone is in the Kitchen.
The backpack is a container.
The backpack contains a thing called the garlic.

Whereas “The wallpaper is scenery in the Kitchen” would not. (I write lines like that all the time in current Inform, but it wouldn’t trouble me too much to explicitly say “a scenery thing”.)

2 Likes

But since indentation is semantically significant, couldn’t it give a more useful error message by detecting an indented line after a full stop?

1 Like

Possibly. Then what? Do you document that top-level assertions may not be indented? Or are you just looking at the indentation to decide what error message to produce? That will still be wrong in some circumstances.

The point is that producing the right error message is hard because it depends on what the author didn’t write, which mean you’re always guessing about something.

(Still has nothing to do with assertion inference, is the other point.)

2 Likes
No doubt about it, you have not even
*tried* to make a Sail program. This
is not a sail program, and I have no
idea what it is. Goodbye and be a
better coder next time.

Yes, you’re right. Although, the second message is significantly shorter, and having quotes around the object name would probably give me a fighting chance.

On the other hand, since I’m using indentation as syntax, it could use that to guess something screwy is going on with punctuation and say:

You wrote “Now the incredible bouncy ball is squashed.” at the same indentation level as a previous phrase, but the previous phrase was already ended with “ say "The ball splats against the wall. It wasn't very bouncy.".”

Probably the solution is that I should get out of the habit of putting full stops in, since they never help AFAIK, and only cause this sort of problem.

That seems perfectly reasonable to me; it becomes the author’s responsibility to formally declare the kind of any object, once and only once. If the theoretical use option were active, the compiler would be on pretty firm footing to call into question anything without such a declaration as a probable typo instead of inferring that something new exists.

That wasn’t a long argument at all!

(Of course, I’m not likely to be one of the people using any such option, so it would be better to hear opinions from those who would.)

1 Like

Maybe a style linter would help. I never use periods in multi-line phrases/rules, only semicolons. Another style recommendation could be that phrases/rules ending in a period need to be followed by a blank line. If we wanted style guidelines like those to be followed uniformly then the compiler could make a warning if you don’t follow them.

1 Like

I’d be okay with those two and I’m somewhat hard-pressed to think of anything else I could even tolerate.

I would prefer the second rule be Multi-line phrases/rules ending in a period need to be followed by a blank line. Things like this look fine to me. Although, now I think about it, I guess definitions aren’t rules or phrases? I’d want the same rule to apply to multi-line definitions, either way.

Definition: A supporter is occupied if something is on it.
Definition: A container is occupied if something is in it.
Definition: A room is occupied if someone is in it.

The term I, personally, have settled on (and is defensible in terms of terminology used in the literate source) is that definitions, rules, and phrases, are imperative code blocks or just imperative blocks. (Or I suppose the Definition case is more like: can be an imperative block.)

(I used to call out when <scene> begins/ends and at 9:15 am/the time when the vase is broken as others, but, really when <scene> begins/ends are rulebooks and the things you create using them are rules, and the at <time/time when condition> things are rules, just weird rules that exist outside of a rulebook.)

2 Likes