Re: Append
- Posted by _tom (admin) Sep 29, 2014
- 1499 views
I appreciate your efforts to improve the documentation, it can be a thankless task. If you do it poorly everybody gripes and if you do it well almost nobody notices.
Thankyou.
_tom
I like the the idea of a sequence as a "list."
The promotion of an atom to a sequence when used with prepend/append is not working in 4.1AL . This just illustrates the problems in creating documentation.
The documentation will need a response to the fact that Euphoria does not have an array data-type. The matrix description is one possible start on this topic.
Here are some ideas to describe "append" and related topics:
Sequence Anatomy
This is how we describe a sequence:
┐ first last │ list items ↓ ↓ │ ┐ ┘ 1 2 3 4 │ $ │ subscript INDEX values length(s)│ ┌ ┘ sequence │ s = { a, b, c, d } └ -- ┐ -- 0 1 2 3 4 5 │ function ARGUMENT values -- ┘ ┐ -- ↑ ↑ │ -- head tail │ to inset or connect new items -- ┘
An index is "an integer ranging from one to the length of the sequence; Euphoria uses one-based indexing." The first item is "indexed as s[1]." The last item is "indexed as s[$] which is the same as s[length(s)] ."
The head of a sequence is "the empty space before the first item s[1] ."
The tail of a sequence is "the empty space after the last item s[$] ."
The length "for a sequence is the count of the top-level items in a sequence; an empty sequence has 0 zero length." Use the length function to get the length of any data-object. The length of an atom is 1 one.
Insetting: prepend, insert, append
The insert function has three arguments: who, what, where.
- Who: the sequence; the target of the renovation.
- What: item; data-object to be inset.
- Where: index; future location for the new item.
The insert function insets a new item just before the where argument of the target sequence.
If it helps, you can pretend that the head and tail are "invisible" items in a sequence list. That explains why you can use function argument values, like 0 zero, that are outside the values allowed for item indexing.
-- "head" "tail" -- ↓ ↓ sequence s = { item1, item2, item3 }
The functions prepend (inset before first item) and append (inset after last item) are special cases of the the insert function. All insetting functions increase length by one.
- prepend insets an item at the head
- insert insets anywhere in a sequence
- append insets an item at the tail
INSET | Head | Anywhere | Tail | ||||
---|---|---|---|---|---|---|---|
◄ | ▼ | ► | |||||
prepend | ◄ | prepend(s,x) | |||||
insert | ◄ ▼ ► | insert(s,x, 1) | insert(s,x,i) | insert(s,x, length(s)+1) | |||
append | ► | append(s,x) |
The append function is probably the most commonly used function. Each time you use append you add one item to the end of your sequence list.
Example 1:
-- the possible insert locations sequence s = {1,2,3} for i=0 to length(s)+1 do ? insert(si, 99, i ) end for -- the output is -- {99,1,2,3} -- {99,1,2,3} -- same as prepend(s,99) -- {1,99,2,3} -- {1,2,99,3} -- {1,2,3,99} -- same as append(s,99)
Example 2:
-- prepend -- inset at "head" before first item s = { 'a', 'b', 'c', 'd' } s = prepend(s, 100} --> s is { 100, 'a', 'b', 'c', 'd' } -- same as prepend S = { 'a', 'b', 'c', 'd' } S = insert(s, {"cat","dog"}, 1) --> S is { {"cat","dog"}, 'a', 'b', 'c', 'd' }
Example 3:
-- append -- inset at "tail" after last item s = { 'a', 'b', 'c', 'd' } s = append(s, 100} --> s is { 'a', 'b', 'c', 'd', 100 } -- same as append S = { 'a', 'b', 'c', 'd' } S = insert(s, {"cat","dog"}, length(S)+1 ) --> S is { 'a', 'b', 'c', 'd', {"cat","dog"} }
A common use for append is to make a list of lists. It helps if you start with an empty list:
Example 4:
sequence mylists = {} sequence list1 = { "12", "23" } sequence list2 = { "34", "45" } mylists = append(mylists, list1 ) --> mylists is { { "12", "23" } } mylists = append(mylists, list2 ) --> mylists is { -- { "12", "23" }, -- { "34", "45" } -- }
Example 5:
A commonly used Euphoria idiom for making a list of lists is to write:
sequence mylists sequence list1 = { "12", "23" } sequence list2 = { "34", "45" } mylists = append( { list1 }, list2 )
The result is the same as Example 4.
- Possible Future enhancement
- The prepend and append functions are especially flexible when used with atoms. If the first argument is an atom it will be promoted to a one item sequence; then the second argument is inset as one more item.
Example 6:
/* ? prepend(3,12) -- atom 3 is not promoted to sequence {3} --> error -- first argument of prepend must be a sequence */ ? prepend( {3}, {12} ) --> {{12},3} ? append( {}, {'a','b'} ) -- object inset into the tail of empty sequence --> { {'a','b'} } ? append( {'a','b'}, {} ) -- empty sequence inset into the tail of a sequence --> {'a','b',{}}
Connect: &, splice, &
Connecting "adds two objects together to make a longer object." The final length is the sum of the two original lengths.
CONNECT | Head | Anywhere | Tail | ||||
---|---|---|---|---|---|---|---|
◄ | ▼ | ► | |||||
& | ◄ | x & s | |||||
splice | ◄ ▼ ► | splice(s,x, 1) | splice(s,x,i) | splice(s,x, length(s)+1) | |||
& | ► | s & x |
Connecting with &
Concatenation is "a binary operation using the & concatenation operator that joins two objects together seamlessly." When two atoms are concatenated they make a two item sequence. When an atom is concatenated to a sequence the atom is added as one item. Sequences are connected tail to head.
You can join a object x to the head of object s by writing x & s, or you can join object x to the tail of object s by writing s & x.
While we do not consider a number to have length it is convenient to think of an atom as having a length of one. This is because one atom concatenated to a sequence increases length by one; two atoms concatenated together make a sequence of length two.
Any data-object is just one item in a sequence; an atom, sequence, string, or nested sequence are all one item; each has a length of one.
Example 1:
sequence s = 2 & 8 --> s is { 2, 8 } -- length 1 + 1 is two sequence S = { 'a', 'b', 'c', 'd' } S = S & 100 --> S is { 'a', 'b', 'c', 'd', 100 } -- length 4+1 is five --> S is "abcdd" -- 'd' is ASCII 100 sequence g = "Hello" g = g & " Euphoria" --> g is "Hello Euphoria" -- length 5+9 is fourteen sequence x = { "hello", 10, -2 } x = { "open", "Euphoria } & x --> x is { "open", "Euphoria, "hello", 10, -2 } -- length 2+3 is five
Connecting with splice
The splice function will "connect an object, seamlessly, anywhere in a sequence list; the new object appears before the 'index' value used as an argument."
The & concatenation operator and splice function both increase the length of a sequence by the length of object being connected.
Concatenating x & s is the same as splice(s,x,1) where the new object is connected before the first item.
Concatenating s & x is the same as splice(s,x,length(s)+1) where the new object is connected after the last item.
Example 2
-- the possible splice locations sequence si = { 1, 2, 3 } for i=0 to length(si)+1 do ? splice(si, {99,99,99}, i ) end for -- the output is -- {99,99,99,1,2,3} -- {99,99,99,1,2,3} -- same as {99,99,99} & {1,2,3} -- {1,99,99,99,2,3} -- {1,2,99,99,99,3} -- {1,2,3,99,99,99} -- same as {1,2,3} & {99,99,99}