Chapter 20: Lists
20.5. Building lists

We have already seen "add... to...". This in fact comes in two forms:

add V to L;
add V to L, if absent;

The former always adds V to L, while the latter does so only if V is not already somewhere in L. (Both forms are allowed only if V is compatible with the kind of entries which is supposed to be stored in L.) V is ordinarily added at the end of L, unless we specify otherwise, for instance with:

add V at entry 3 in L;
add V at entry 3 in L, if absent;

For instance "add V at entry 1 in L" adds V at the beginning, moving all of the existing entries up by one place. (If there are N entries in L, then we can add at any of entries 1 up to N+1: adding at entry N+1 means adding at the end.)

A list is allowed to contain duplicates, and the order matters. For instance:

let L be {2, 2, 3};

makes L into "2, 2 and 3". This is a different list to the one made by:

let M be {2, 3, 2};

even though L and M have the same values, repeated the same number of times - for two lists to be equal, they must have the same kind of entry, the same number of entries, and the same entries in each position.

We can also strike out values:

remove 2 from L;
remove 2 from L, if present;

These each go through L and remove every 2 that's present: so for instance the L above would be reduced down to just a single entry, 3. Ordinarily "remove 2 from L" produces a run-time problem if L does not contain the value 2, but using the "if present" option lets us off this: the phrase then does nothing if L does not contain the value to be removed.

Entries in given positions in the list can also be removed:

remove entry 3 from L;
remove entries 4 to 6 from L;

The entries are numbered from 1, so that "remove entry 1 from L" takes away the first entry. (The others automatically shuffle down.)

Adding entries one at a time is pretty tiresome, but we can also append a whole list of extra entries X onto the end of any already-existing list L:

let L be {2, 3};
add {60, 168} to L;

makes L into {2, 3, 60, 168}. This is, of course, only allowed if the values in X are compatible with the kind of value L is supposed to hold. Alternatively, we can add a set at the front, or even somewhere in the middle:

add {60, 168} at entry 2 in L;

produces {2, 60, 168, 3}, with the added entries beginning at entry 2.

Symmetrically, we can also remove from a list:

let L be {2, 3, 7};
remove {3, 7} from L;

makes L into simply {2}. (If L and the list to be added are both very large, this can be a slow process, and we might do better by sorting them and trying a more sophisticated method. But this is convenient for anything reasonable-sized.)


370
* Example  Robo 1
A robot which watches and records the player's actions, then tries to repeat them back in the same order when he is switched into play-back mode.

RB

"Robo"

The Experimentation Chamber is a room. Robo is a man in the Experimentation Chamber. "Robo, your prototype tin companion, stands awkwardly beside you. In the middle of his chest is a red enamel button[if the red button is switched on], currently depressed[otherwise], currently un-depressed[end if]."

The red button is a device. It is part of Robo. Instead of pushing the red button: if the red button is switched off, try switching on the red button; otherwise try switching off the red button.

After switching on the red button:
    say "CLICK! Robo is now in play-back mode."

After switching off the red button:
    say "CLACK! Robo is now in observation mode."

Definition: Robo is watching if the red button is switched off.

The current instruction set is a list of stored actions that varies.

After doing something when Robo is watching and Robo can see the player:
    change the actor to Robo;
    add the current action to the current instruction set;
    change the actor to the player;
    say "Robo watches you [the current action][one of], his yellow eyes lamp-like and observant[or]. In his metal head, gears whirr[or], his brushed-copper handlebar moustaches twitching[or] impassively[at random].";
    continue the action.

Every turn when Robo is not watching:
    if the number of entries in the current instruction set is 0
    begin;
        say "Robo has run out of behavior and grinds to an (expectant) halt.";
        now the red button is switched off;
    otherwise;
        let the next task be entry 1 of the current instruction set;
        try the next task;
        remove entry 1 from the current instruction set;
    end if.

The red block and the blue cylinder are things in the Experimentation Chamber. The counter is a supporter in the Experimentation Chamber. The counter is scenery.

Report Robo examining Robo:
    say "Robo examines each of his hands in turn, then each of his legs (bending over mostly double in the middle to do this)." instead.

Report Robo examining the player:
    say "Robo stares at you, unblinkingly, for several seconds together[if a random chance of 1 in 7 succeeds]. His left moustache-bar twitches infinitesimally upward[end if]." instead.

Report Robo taking the cylinder:
    say "[one of][Robo] needs several attempts to get his metal fingers around [the cylinder] -- they are not designed for grasping small objects elegantly. But at last he succeeds[or]Once again, Robo struggles a bit before picking up [the cylinder][stopping]." instead.

Test me with "z / take cylinder / take block / put cylinder on counter / put block on counter / x robo / x me / get block / drop block / press red button / z / z / z / z / z / z / z / z / z / z".


PreviousContentsNext