Improving the NOUN dict flag

Branching off this thread: LanguageVerbMayBeName - why not use dictionary data? It mentioned the high bit (value 128, or DICT_NOUN) of the dict word flags (#dict_par1). I said:

(The way the Inform compiler assigns that bit isn’t very rigorous. The library shouldn’t rely on it without considering the risk of false positives.)

More explanation: The I6 compiler sets the NOUN flag for dict words that appear in an expression, either in a function or as data.

For example, dict words in a name property get the flag. (That makes sense.) Also dict words that are mention in a parse_name routine. (Fine.) Also dict words that are mentioned in any other property or routine, because, um, what if a parse_name routine looks at that property? Or calls that routine? It could, you know!

The only place where dict words don’t get the NOUN flag is in a Verb grammar declaration. (And in the little-used Dictionary directive, where you can explicitly set flags.)

Basically, the compiler takes a very conservative view of what might be an object name, and therefore a whole lot of words get the NOUN flag just in case. For example, look at this routine in the standard library:

[ LanguageVerb i;
    switch (i) {
      'i//','inv','inventory':
               print "take inventory";
      'l//':   print "look";
      'x//':   print "examine";
      'z//':   print "wait";
      ! ...more of these in 6/12...
    }
    rtrue;
];

Those are words mentioned in a routine; therefore they get the NOUN flag. The whole point of this routine is that the argument is a known verb – but the compiler doesn’t know that. Other library routines wind up setting the NOUN flag for 'look', 'go', 'push', 'verbose', 'sit', 'stand', and more. Not ideal!

(Of course, there are plenty of verbs that really are also nouns, in a given game. For example, in Adventure, 'oil' is both a noun and a verb. But the library routines mentioned above make this happen unnecessarily for a bunch of words.)


I don’t intend to change the default compiler behavior. This is definitely one of those “been this way for decades, don’t change the behavior” situations. However, I have a notion for improving this on an opt-in basis, so that future games (and libraries) can use the NOUN flag in a smarter way.

I want to add a new dict word suffix, //w, which means “This word is not being used as a noun right here.” (It may of course be used as a noun elsewhere.) You could then rewrite the above routine:

[ LanguageVerb i;
    switch (i) {
      'i//w','inv//w','inventory//w':
                print "take inventory";
      'l//w':   print "look";
      'x//w':   print "examine";
      'z//w':   print "wait";
      ! ...etc

(The “w” stands for, um, “word”, I guess. I don’t want to use //v because we’re not setting the VERB flag; we’re just declining to set the NOUN flag.)

(Maybe //~n? That would be extra work, though, and it would lead to the question of what //~p means. Better not.)

3 Likes

//w, of course, stands for “used as a verb”.

Seems like reasonable modification.

Wouldn’t //~p mean that the word is not plural, i.e. the same as no suffix //p at all, right?

Fully concur and agree with Zarf on the proposal; I note that ‘stand’ as noun, IS a legitimate noun, having a sizeable variety of implementation.

Best regards from Italy,
dott. Piergiorgio.

I was actually thinking about posting a feature request for exactly this!

It does make sense to keep the default behavior; having to remember to specify a special //n suffix to positively request the noun bit would not be fun. My thought was to use the suffix //u (for “unmarked”) or possibly //x (like crossing out), but //w would be fine.

Good, I’m glad other folks were thinking along the same lines. :)

Wouldn’t //~p mean that the word is not plural, i.e. the same as no suffix //p at all, right?

Yeah, but people might think that it removes the plural flag. Eh, it’s not terrible. I’ll see how the code comes out.

1 Like