Inform 7 Home Page / Documentation

§22.7. Kind variables

The examples of generic phrases in the previous section were really only toy examples. Suppose we want a phrase which will take any arithmetic value and triple it. We could do something like this:

To triple (V - arithmetic value): say "[V times 3]."

But this only prints the answer. Suppose we want to be given the value back, instead: how can we write the phrase? The trouble is that, not knowing the kind of V, we can't say what kind will be produced. We need a way of saying "the same kind comes out as went in". Inform expresses that using kind variables:

To decide which K is triple (original - arithmetic value of kind K):
    decide on 3 times the original.

Here, K stands for any kind which matches "arithmetic value". Inform supports exactly 26 of these symbols, which are written A to Z, but it's customary to use K and L. (They can be written in the plural if we like: e.g., "list of Ks". But they must always use a capital letter: "list of k" is not allowed.)

Each symbol we use has to be declared in exactly one of the bracketed ingredients for the phrase - here, the declaration is "arithmetic value of kind K". That creates K and says that it has to be arithmetic; if we'd just said "value of kind K", it could have been anything. (Alternatively, we could use any of the kinds of kind in the previous section.)

For a more ambitious example, here is one way to define the mapping operation described earlier in the chapter:

To decide what list of L is (function - phrase K -> value of kind L)
    applied to (original list - list of values of kind K):
    let the result be a list of Ls;
    repeat with item running through the original list:
        let the mapped item be the function applied to the item;
        add the mapped item to the result;
    decide on the result.

Here we need two symbols to explain the complicated way that the values going in and out have to match up to each other. Note also the way that the temporary variable "result" is created:

let the result be a list of Ls;

Ordinarily, of course, "L" is not a kind. But within the body of a phrase definition, it means whatever kind L matched against.

When a symbol occurs several times in the same definition, subtle differences can arise according to which appearance is the declaration. These are not quite the same:

To hunt for (V - value of kind K) in (L - list of Ks): ...
To hunt for (V - K) in (L - list of values of kind K): ...

The difference arises - though very rarely - if V has some different kind compared to the list entries, but which can be used as if it were of that kind. For example,

hunt for the player's command in {"take all", "wait"};

Here V is a snippet, but L is a list of texts; and a snippet can be used in place of a text, but not vice versa. So this will match the second definition, because K is set to "text", but it won't match the first, where K is set to "snippet".

arrow-up.png Start of Chapter 22: Advanced Phrases
arrow-left.png Back to §22.6. Generic phrases
arrow-right.png Onward to §22.8. Matching the names of kinds