APPEND

The 'append function takes a series and a value as arguments. It
modifies the sequence referenced by the first argument, copying the
value of the second argument onto its end (increasing the length of
the sequence as a consequence).  The value of ANY series that refers
to this sequence is therefore changed by 'append (including the
first argument!)  After the modification is complete, 'append
returns a series referring to the same sequence, but at an index 
of 1.  (This result is equivalent to applying 'head to any series
that references that same sequence.)

After the last diagram above, evaluating:

    r: append b "X"

produces the following state:

    a ---> {{string! 1 *}}
                       |
                       V
                       <<#"1" #"2" #"3" #"4">>
                       ^
                      / \
                     /   \
    b -> {{string! 2 *}}  \
                           \
    r -------> {{string! 1 *}}

The returned value of "1234X" is coincidentally the same as the
value of a, which currently refers to the same sequence with an
index of 1.

    >> a: "1234"
    == "1234"
    >> b: next a
    == "234"
    >> r: append b "X"
    == "1234X"
    >> b
    == "234X"
    >> a
    == "1234X"

If the first argument is a string, the second argument's value is
translated into a string, whose sequence of characters are all
appended onto the first argument's sequence.

    >> a: "ijkl"
    == "ijkl"
    >> append a -3 * 4
    == "ijkl-12"

If both arguments evaluate to blocks, the elements of the second
argument's sequence are individually appended to the first
argument's sequence by default.

    >> a: [1 2 3 4]
    == [1 2 3 4]
    >> append a [9 8 7]
    == [1 2 3 4 9 8 7]

However, if both arguments are blocks and the /only refinement is
used, a REFERENCE to the second argument (in its entirety) is the
only thing appended.

    >> a: [1 2 3 4]
    == [1 2 3 4]
    >> append/only a next [9 8 7]
    == [1 2 3 4 [8 7]]
    >> head fifth a
    == [9 8 7]

This last case could be diagramed as:

    a -> {{block! 1 *}}
                    |
                    V
                    <<1 2 3 4 *>>
                              |
                              V
                              {{block! 2 *}}
                                         |
                                         V
                                         <<9 8 7>>

The last position is now occupied by an anonymous block with an
index of 2.


INSERT

The 'insert behaves in a manner analogous to 'append, with a few
exceptions:

*  the insertion of values into the first argument's sequence takes
   place at the first argument's index, and
*  the result returned by 'insert is a series referring to the
   modified sequence, but with a position IMMEDIATELY AFTER the
   inserted element(s).

(The /part and /dup refinements will be ignored for now.  They offer
convenient variations on the 'insert theme, but no fundamentally
new insights.)

Evaluating the expressions:

    a: "1234"
    b: next a
    r: insert b "XYZ"

should produce this state of affairs:

    b -------> {{string! 2 *}}
                          /
    a -> {{string! 1 *}} /
                      \ /
                       V
                       <<#"1" #"X" #"Y" #"Z" #"2" #"3" #"4">>
                       ^
                       |
    r ---> {{string! 5 *}}

The index of the new series returned by 'insert is explained in the
REBOL documents as allowing multiple 'insert operations to place the
inserted data in an intuitively natural order.  'insert produces a
string that may be operated on immediately by another function.  To
see this in action, consider the effect of evaluating:

    a: "1234"
    b: next a
    r: insert insert insert b "Fee" "Fie" "Foe"

The first two lines establish:

    a -> {{string! 1 *}}
                     |
                     V
                     <<#"1" #"2" #"3" #"4">>
                     ^
                     |
    b -> {{string! 2 *}}

Ignoring a for the moment (because its series entity is unchanged),
evaluating  insert b "Fee"  produces:

    b -> {{string! 2 *}}
                     |
                     V
                     <<#"1" #"F" #"e" #"e" #"2" #"3" #"4">>
                     ^
                     |
         {{string! 5 *}}  (FIRST INTERMEDIATE ANONYMOUS RESULT)

 The three characters of "Fee" were inserted into the sequence
 beginning at position 2 (the index of b's value).  The result of
 the insertion has an index of 5, as that is the next character
 AFTER the inserted characters.  Performing the second insertion
 with  insert ...previous result... "Fie"

         {{string! 5 *}}  (FIRST INTERMEDIATE ANONYMOUS RESULT)
                     |
                     V
                     <<#"1" #"F" #"e" #"e" #"F" #"i" #"e"
                     ^                     #"2" #"3" #"4">>
                     |
         {{string! 8 *}}  (SECOND INTERMEDIATE ANONYMOUS RESULT)

The three characters of "Fie" were inserted beginning at position 5
(the first intermediate result's index) and NOT at 2 (the index of
b's value).  The side effect is different from the returned result.

Finally, the outermost 'insert is performed, producing:

        {{string! 8 *}}  (SECOND INTERMEDIATE ANONYMOUS RESULT)
                    |
                    V
                    <<#"1" #"F" #"e" #"e" #"F" #"i" #"e"
                    ^      #"F" #"o" #"e" #"2" #"3" #"4">>
                    |
        {{string! 11 *}}  (THIRD INTERMEDIATE ANONYMOUS RESULT)

and r is set to refer to this third result.  Since this string
indexes at position 11 into a sequence of 13 characters, only
the last three characters will appear when the value of r is
printed by the interpreter.  The entities referred to by both
a and b are unchanged, in the sense that they still refer to
positions 1 and 2 respectively of the same sequence.  However,
since the sequence has changed, their printed values include the
new data inserted into the sequence.

    >> a: "1234"
    == "1234"
    >> b: next a
    == "234"
    >> r: insert insert insert b "Fee" "Fie" "Foe"
    == "234"
    >> a
    == "1FeeFieFoe234"
    >> b
    == "FeeFieFoe234"

Thus the model has correctly predicted the output of typing the
expressions above into the REBOL interpreter's console.


(continued in essay/5)

Reply via email to