Expand/Shrink

Other Operations on Sequences

Some other important operations that you can perform on sequences have English names, rather than special characters. They are described in detail in Library Routines, but are important enough that we should mention them here before proceeding. You call these operations as if they were subroutines, although they are actually implemented much more efficiently than that.

length(s) tells you the length of a sequence s, as does the ~s shorthand equivalent (which should not be confused with a bitwise not, use not_bits() for that instead). This is the number of elements in s. Some of these elements may be sequences that contain elements of their own, but length just gives you the "top-level" count. You will get an error if you ask for the length of an atom. e.g.
    length({5,6,7})             -- 3
    length({1, {5,5,5}, 2, 3})  -- 4 (not 6!)
    length({})                  -- 0
    length(5)                   -- error!
repeat(item, count) makes a sequence that consists of an item repeated count times. e.g.
    repeat(0, 100)         -- {0,0,0,...,0}   i.e. 100 zeros
    repeat("Hello", 3)     -- {"Hello", "Hello", "Hello"}
    repeat(99,0)           -- {}
The item to be repeated can be any atom or sequence.

append(s, item) creates a new sequence by adding one item to the end of a sequence s.
prepend(s, item) creates a new sequence by adding one element to the beginning of a sequence s.
    append({1,2,3}, 4)         -- {1,2,3,4}
    prepend({1,2,3}, 4)        -- {4,1,2,3}
    append({1,2,3}, {5,5,5})   -- {1,2,3,{5,5,5}}
    prepend({}, 9)             -- {9}
    append({}, 9)              -- {9}
The length of the new sequence is always 1 greater than the length of the original sequence. The item to be added to the sequence can be any atom or sequence.

These two built-in functions, append() and prepend(), have some similarities to the concatenate operator, &, but there are clear differences. e.g.
    -- appending a sequence is different
    append({1,2,3}, {5,5,5})   -- {1,2,3,{5,5,5}}       -- length(3) + <any> ==> length(4)
    {1,2,3} & {5,5,5}          -- {1,2,3,5,5,5}         -- length(3) + length(3) ==> length(6)
    -- appending an atom is the same
    append({1,2,3}, 5)         -- {1,2,3,5}
    {1,2,3} & 5                -- {1,2,3,5}
Beginners often confuse s = append(s,x) with s &= x, so here are two simple rules to memorise:
  • append always and only ever increases the length of s by 1, ditto prepend.
  • use & to construct strings, or to add a variable number of elements to a list or table in one operation.
In addition, s &= "", s &= {}, s = s&"", s = s&{}, s = ""&s, and s = {}&s are all effectively null-ops, except when s is initially an atom or character, in which case s will become a sequence or string of length 1, whereas there are no forms whatsoever of either append or prepend that are null-ops.

Note: append(), prepend(), &, and &= are very heavily optimised on desktop/Phix, and can put the best that JavaScript can offer to utter shame. When (planning on) using pwa/p2js, if at all possible allocate the sequence/array up-front using repeat() and store elements using s[i] = x - you probably won’t notice much difference on desktop/Phix but you almost certainly will in a browser, at least that is when there are > 1,000 added elements. Such pre-allocation, when possible, would always be either a little or a lot faster, never slower.