LISTS
A list is a row of things, kept in the order you put them in: a shopping list, the scores in a game, the names of everyone at the table. In satellite a list is a satellite.container.list, and it is one of the first containers worth learning, because almost every program has something to keep in a row.
Making a list
You write a list with braces, wherever a value can go. {1, 2, 3} is a list of three numbers, {"bread", "milk"} is a list of two strings, and {} is a list with nothing in it yet. satellite.container.list() is the same empty list, written in words.
What goes between < and > says what the list may hold. satellite.container.list<satellite.variable.string> holds only strings, and satl checks every item that goes in. A list with no <> holds anything, even a mix of numbers and text.
(satellite)
satellite.capsule satellite.main()
{
satellite.container.list<satellite.variable.string> shopping = {"bread", "milk"}
shopping.append("eggs")
shopping.insert(1, "tea")
satellite.console.display(shopping)
satellite.console.display(shopping[1])
satellite.console.display(shopping.size)
satellite.console.display(shopping.contains("milk"))
shopping.remove("milk")
shopping[3] = "duck eggs"
satellite.console.display(shopping)
satellite.return(satellite)
}{"tea", "bread", "milk", "eggs"}
tea
4
true
{"tea", "bread", "duck eggs"}A few things to notice:
- Lists count from 1.
shopping[1]is the first item, the way the first line of a page is line 1. There is no item 0. .append(x)adds to the end, and.insert(n, x)puts an item at positionnand moves the rest along.shopping[3] = "duck eggs"replaces item 3. Writing past the end does not make a list longer:.appenddoes that..remove(x)takes out an item by what it is..remove_at(n)takes one out by its position, and.remove_first(),.remove_last(),.truncate(n)and.clear()do what their names say.
Adding it up
A list of numbers can answer questions about itself. .sum adds every item, .max and .min find the largest and the smallest, and .join(separator) makes one string from every item with the separator in between.
(satellite)
satellite.capsule satellite.main()
{
satellite.container.list<satellite.variable.number> scores = {30, 4, 100}
satellite.console.display(scores.sum)
satellite.console.display(scores.max)
satellite.console.display(scores.min)
satellite.console.display(scores.join(" + "))
satellite.console.display(scores.sort().by_value())
satellite.console.display(scores.sort().by_value().reverse())
satellite.console.display(scores)
satellite.container.list<satellite.variable.string> names = {"zoe", "al", "bo"}
satellite.console.display(names.join(", "))
satellite.console.display(names.max)
satellite.console.display(names.sort().by_name())
satellite.container.list<satellite.variable.number> nothing = {}
satellite.console.display(nothing.sum)
satellite.return(satellite)
}134
100
4
30 + 4 + 100
{4, 30, 100}
{100, 30, 4}
{30, 4, 100}
zoe, al, bo
zoe
{"al", "bo", "zoe"}
0.sort() on its own does nothing: follow it with .by_value(), smallest first, or .by_name(), which orders by how each item reads. Put .reverse() after either to go the other way. Sorting hands you a new list and leaves the old one alone, which is why scores still reads {30, 4, 100} at the end. A list of nothing sums to 0.
.sum adds numbers. On a list of strings satl refuses it and points you to .join, which is the way to put text together.
.reserve(n) is for when you know a list is about to grow large: it makes room for n items at once, so the list does not have to keep finding more room as you append. It changes no item, and the list’s size stays what it was.
Going through a list, one item at a time
satellite 004 has no “for each” loop yet, so you walk a list with a counting loop, satellite.statement.for, and read each item by its number. Count from 1 up to and including .size.
(satellite)
satellite.capsule satellite.main()
{
satellite.container.list<satellite.variable.string> class_register = {"ann", "bo", "cy"}
satellite.statement.for(satellite.variable.number i = 1; i <= class_register.size; i++)
{
satellite.console.display(i.to_string() + ". " + class_register[i])
}
satellite.container.list copy = class_register
copy.append("dee")
satellite.console.display(class_register.size)
satellite.console.display(copy.size)
satellite.return(satellite)
}1. ann
2. bo
3. cy
3
4The second half shows something important: copy = class_register copies the list. Changing the copy leaves the original alone. The copy costs nothing until one of the two is changed, so you never pay for a copy you do not use.
When you read past the end
Ask for an item a list does not have and satl stops, names the list, and says how many items it really holds.
(satellite)
satellite.capsule satellite.main()
{
satellite.container.list<satellite.variable.number> scores = {7, 9}
satellite.console.display(scores[3])
satellite.return(satellite)
}--------------------------------------------------------------------------------
SATELLITE CRITICAL ERROR REPORT
--------------------------------------------------------------------------------
S501: LINE_PAST_THE_END
satl(run): scores[3]: there is no such item -- the list holds 2 items, counting
from 1
directory: past_the_end.satl:6
syntax: satellite.console.display(scores[3])
/\
a line was read by its number and the file has no line with that number. Lines
count from 1, and the last one is the file's size.
machine code 47 line_past_the_end -- satl exits with this.
--------------------------------------------------------------------------------The second line of the report is the one to read: it names scores[3] and says the list holds 2 items. The paragraph under the caret is written for files, which count their lines from 1 the same way. scores[0] is refused the same way, because there is no item 0.
Where next
Every list word is in the FULL REFERENCE. A list can hold other lists, which makes a grid: see GRIDS: LISTS OF LISTS. To look things up by a name instead of a number, see MAPS.
