GoloScript Collections Guide

This comprehensive guide presents all available collections in GoloScript, their methods, and advanced usage patterns like collection comprehensions.

Introduction

GoloScript offers several collection types for different use cases:

★ Insight ─────────────────────────────────────
Immutability vs Mutability: GoloScript clearly distinguishes immutable collections (tuples) from mutable ones (arrays, lists, vectors). Tuples guarantee that once created, their elements cannot be modified, making them perfect for constant data and avoiding bugs related to unexpected modifications.

Collection Choice: Use tuples for unchanging data (coordinates, configurations), arrays for fast index access, lists when you need map/filter, and sets to automatically eliminate duplicates.
─────────────────────────────────────────────────


Collection Types

Literal Syntax

# Tuples - immutable
let tuple = [1, 2, 3]
let emptyTuple = []

# Arrays - mutable
let arr = array[1, 2, 3, 4, 5]
let emptyArray = array[]

# Lists - mutable with functional operations
let list = list[10, 20, 30]
let emptyList = list[]

# Vectors - optimized for numbers
let vec = vector[1.1, 2.2, 3.3]
let emptyVec = vector[]

# Sets - no duplicates
let set = set[1, 2, 3, 2, 1]  # Result: set[1, 2, 3]
let emptySet = set[]

# Maps - key-value pairs
let map = map[["name", "Alice"], ["age", 30]]
let emptyMap = map[]

Tuples (immutable)

Tuples are ordered immutable collections. Once created, their elements cannot be modified. All operations return new tuples.

Creation

let tuple1 = [1, 2, 3, 4, 5]
let tuple2 = ["a", "b", "c"]
let emptyTuple = []
let nestedTuple = [[1, 2], [3, 4]]

Available Methods

Method Description Returns Example
size() Number of elements Integer [1,2,3]: size()3
length() Same as size() Integer [1,2,3]: length()3
get(index) Access by index Element [10,20,30]: get(1)20
head() First element Element [1,2,3]: head()1
tail() All except first Tuple [1,2,3]: tail()[2,3]
isEmpty() Check if empty Boolean []: isEmpty()true
contains(val) Contains element Boolean [1,2,3]: contains(2)true
indexOf(val) Index of element Integer ["a","b","c"]: indexOf("b")1
subTuple(start, end) Extract sub-tuple (end inclusive) Tuple [0,1,2,3,4]: subTuple(2,4)[2,3,4]
extend(...vals) Add elements Tuple (new) [1,2]: extend(3,4)[1,2,3,4]
reverse() Reverse order Tuple (new) [1,2,3]: reverse()[3,2,1]
toArray() Convert to array Array [1,2,3]: toArray()array[1,2,3]
equals(other) Equality Boolean [1,2]: equals([1,2])true
hashCode() Hash code Integer [1,2,3]: hashCode()
compareTo(other) Lexicographic comparison Integer [1,2,3]: compareTo([1,2,4])-1

Examples

let fruits = ["apple", "banana", "orange"]

# Element access
println(fruits: get(0))        # apple
println(fruits: head())        # apple
println(fruits: tail())        # [banana, orange]

# Search
println(fruits: contains("banana"))  # true
println(fruits: indexOf("orange"))   # 2

# Extraction
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
println(numbers: subTuple(2, 5))     # [2, 3, 4]

# Adding (returns NEW tuple)
let colors = ["red", "green"]
let colors2 = colors: extend("blue", "yellow")
println(colors)   # [red, green] (unchanged)
println(colors2)  # [red, green, blue, yellow]

# Reversing (returns NEW tuple)
let nums = [1, 2, 3, 4, 5]
let reversed = nums: reverse()
println(nums)      # [1, 2, 3, 4, 5] (unchanged)
println(reversed)  # [5, 4, 3, 2, 1]

# Method chaining
let result = [5, 4, 3, 2, 1]
  : reverse()           # [1, 2, 3, 4, 5]
  : tail()              # [2, 3, 4, 5]
  : extend(6, 7)        # [2, 3, 4, 5, 6, 7]

Tuple ↔ Array Conversion

# Tuple to Array
let myTuple = [1, 2, 3]
let myArray = myTuple: toArray()
myArray: set(0, 999)  # Arrays are mutable
println(myTuple)  # [1, 2, 3] (unchanged)
println(myArray)  # [999, 2, 3]

# Array to Tuple
let arr = array[10, 20, 30]
let tup = tupleFromArray(arr)  # Global function

Arrays (mutable)

Arrays are ordered mutable collections with fast index access.

Creation

let arr = array[1, 2, 3, 4, 5]
let emptyArr = array[]
let strings = array["hello", "world"]

Available Methods

Method Description Returns Mutates? Example
size() Number of elements Integer No array[1,2,3]: size()3
length() Same as size() Integer No array[1,2,3]: length()3
get(index) Access by index Element No array[10,20,30]: get(1)20
set(index, val) Modifies element void Yes arr: set(0, 99)
head() First element Element No array[1,2,3]: head()1
tail() All except first Array No array[1,2,3]: tail()array[2,3]
isEmpty() Check if empty Boolean No array[]: isEmpty()true
contains(val) Contains element Boolean No array[1,2,3]: contains(2)true
indexOf(val) Index of element Integer No array["a","b"]: indexOf("b")1
append(val) Add element Array (new) No array[1,2]: append(3)array[1,2,3]
reverse() Reverse order Array (new) No array[1,2,3]: reverse()array[3,2,1]

Examples

# Creation and modification
let numbers = array[1, 2, 3, 4, 5]

# Access
println(numbers: get(0))     # 1
println(numbers: get(2))     # 3

# IN-PLACE modification
numbers: set(2, 99)
println(numbers)             # array[1, 2, 99, 4, 5]

# Search
let fruits = array["apple", "banana", "orange"]
println(fruits: contains("banana"))   # true
println(fruits: indexOf("orange"))    # 2

# Append returns NEW array
let colors = array["red", "green"]
let colors2 = colors: append("blue")
println(colors)   # array[red, green] (unchanged)
println(colors2)  # array[red, green, blue]

# Chaining
let data = array[5, 4, 3, 2, 1]
let result = data: reverse(): tail(): append(99)
println(result)  # array[2, 3, 4, 5, 99]

# Iteration with while
var i = 0
while i < numbers: length() {
  println("numbers[" + str(i) + "] =", numbers: get(i))
  i = i + 1
}

# Iteration with foreach
foreach num in numbers {
  println("Value:", num)
}

Lists (mutable)

Lists are ordered mutable collections with powerful functional operations (map, filter).

Creation

let list = list[1, 2, 3, 4, 5]
let emptyList = list[]
let names = list["Alice", "Bob", "Charlie"]

Available Methods

Method Description Returns Example
size() Number of elements Integer list[1,2,3]: size()3
length() Same as size() Integer list[1,2,3]: length()3
get(index) Access by index Element list[10,20,30]: get(1)20
head() First element Element list[1,2,3]: head()1
tail() All except first List list[1,2,3]: tail()list[2,3]
isEmpty() Check if empty Boolean list[]: isEmpty()true
contains(val) Contains element Boolean list[1,2,3]: contains(2)true
indexOf(val) Index of element Integer list["a","b"]: indexOf("b")1
append(val) Add element List (new) list[1,2]: append(3)list[1,2,3]
reverse() Reverse order List (new) list[1,2,3]: reverse()list[3,2,1]
map(fn) Transform each element List list[1,2,3]: map(|x| -> x * 2)
filter(fn) Keep matching elements List list[1,2,3,4]: filter(|x| -> x % 2 == 0)

Map - Transform Each Element

let numbers = list[1, 2, 3, 4, 5]

# Double each number
let doubled = numbers: map(|x| -> x * 2)
println(doubled)  # list[2, 4, 6, 8, 10]

# Square each number
let squared = numbers: map(|x| -> x * x)
println(squared)  # list[1, 4, 9, 16, 25]

# Transform strings
let names = list["alice", "bob", "charlie"]
let uppercased = names: map(|name| -> name: toUpperCase())
println(uppercased)  # list[ALICE, BOB, CHARLIE]

# With formatting
let greetings = names: map(|name| -> "Hello, " + name + "!")
println(greetings)  # list[Hello, alice!, Hello, bob!, ...]

Filter - Keep Matching Elements

let allNumbers = list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Keep only even numbers
let evens = allNumbers: filter(|x| -> (x % 2) == 0)
println(evens)  # list[2, 4, 6, 8, 10]

# Keep only > 5
let greaterThan5 = allNumbers: filter(|x| -> x > 5)
println(greaterThan5)  # list[6, 7, 8, 9, 10]

Chaining Map and Filter

let numbers = list[1, 2, 3, 4, 5]

# Chaining map
let result = numbers
  : map(|x| -> x * 2)        # Double: [2, 4, 6, 8, 10]
  : map(|x| -> x + 1)        # +1:     [3, 5, 7, 9, 11]
  : map(|x| -> x * x)        # Square: [9, 25, 49, 81, 121]

println(result)

# Combining filter and map
let data = list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenDoubled = data
  : filter(|x| -> (x % 2) == 0)  # Keep even: [2, 4, 6, 8, 10]
  : map(|x| -> x * 2)             # Double:    [4, 8, 12, 16, 20]

println(evenDoubled)

Practical Example - Temperature Conversion

let celsius = list[0, 10, 20, 30, 40]

# Celsius to Fahrenheit: F = C * 9/5 + 32
let fahrenheit = celsius: map(|c| -> c * 9.0 / 5.0 + 32.0)

println("Celsius:", celsius)
println("Fahrenheit:", fahrenheit)
# Fahrenheit: list[32.0, 50.0, 68.0, 86.0, 104.0]

Using Named Functions

function triple = |x| { return x * 3 }
function isOdd = |x| { return (x % 2) != 0 }

let sample = list[1, 2, 3, 4, 5]
println(sample: map(triple))      # list[3, 6, 9, 12, 15]
println(sample: filter(isOdd))    # list[1, 3, 5]

Vectors

Vectors are ordered mutable collections optimized for numeric data.

Creation

let vec = vector[1.1, 2.2, 3.3]
let integers = vector[100, 200, 300]
let emptyVec = vector[]

Methods

Vectors support the same methods as arrays (get, set, size, etc.).

let vec = vector[1.5, 2.5, 3.5, 4.5]
println(vec: size())       # 4
println(vec: get(0))       # 1.5
vec: set(0, 9.9)
println(vec)               # vector[9.9, 2.5, 3.5, 4.5]

Sets

Sets are unordered collections that automatically eliminate duplicates.

Creation

let set1 = set[1, 2, 3, 2, 1]  # Result: set[1, 2, 3]
let set2 = set["a", "b", "c"]
let emptySet = set[]

Characteristics

# Duplicates are removed
let numbers = set[1, 2, 3, 2, 1, 3, 4]
println(numbers)  # set[1, 2, 3, 4]

# Ideal for eliminating duplicates from a list
let duplicates = list[1, 2, 2, 3, 3, 3, 4]
let unique = set[x foreach x in duplicates]
println(unique)   # set[1, 2, 3, 4]

Maps (dictionaries)

Maps are collections of key-value pairs.

Creation

let person = map[["name", "Alice"], ["age", 30], ["city", "Paris"]]
let numbers = map[[1, "one"], [2, "two"], [3, "three"]]
let emptyMap = map[]

Access and Modification

let person = map[["name", "Alice"], ["age", 30]]

# Access via get()
println(person: get("name"))  # Alice
println(person: get("age"))   # 30

# Check key existence
println(person: containsKey("name"))  # true
println(person: containsKey("email")) # false

# Iterate over keys
foreach key in person: keys() {
  println(key + ":", person: get(key))
}

Collection Comprehensions

Comprehensions provide a concise syntax for creating collections from other collections.

Basic Syntax

# General syntax
collection[expression foreach variable in source]

# With filter
collection[expression foreach variable in source when condition]

# Nested foreach
collection[expression foreach var1 in source1 foreach var2 in source2]

Simple Examples

# Double each number
let doubles = list[x * 2 foreach x in [1, 2, 3, 4, 5]]
# Result: list[2, 4, 6, 8, 10]

# Keep only even numbers
let evens = list[x foreach x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] when x % 2 == 0]
# Result: list[2, 4, 6, 8, 10]

# With range
let squares = list[x * x foreach x in [1..10]]
# Result: list[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Comprehensions with Ranges

# Range: [start..end] (end inclusive)
let range = [1..5]  # [1, 2, 3, 4, 5]

# Usage in comprehension
let squares = list[x * x foreach x in [1..10]]
println(squares)
# list[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Multiple Conditions (multiple when)

# Multiple conditions
let filtered = list[x foreach x in [1..20] when x % 2 == 0 when x > 10]
# Result: list[12, 14, 16, 18, 20]
# (Even AND > 10)

Nested foreach (Cartesian Product)

# Cartesian product
let sums = list[x + y foreach x in [1, 2, 3] foreach y in [10, 20, 30]]
# Result: list[11, 21, 31, 12, 22, 32, 13, 23, 33]

# Create coordinates
let coords = list[[x, y] foreach x in [1..3] foreach y in [1..3]]
# Result: [[1,1], [1,2], [1,3], [2,1], [2,2], [2,3], [3,1], [3,2], [3,3]]

# With filter
let filteredCoords = list[[x, y] foreach x in [1..5] foreach y in [1..5] when x < y]
# Result: Only pairs where x < y

Set Comprehensions

# Set automatically eliminates duplicates
let remainders = set[x % 5 foreach x in [1..20]]
# Result: set[1, 2, 3, 4, 0]
# (Only unique remainder values from division by 5)

String Iteration

# Iterate over string characters
let chars = list[c foreach c in "GOLO"]
# Result: list[G, O, L, O]

# Transform characters
let excited = list[c + "!" foreach c in "abc"]
# Result: list[a!, b!, c!]

Advanced Comprehensions

Tuple Destructuring

# Destructuring: extract elements from tuples
let couples = [[1, 10], [2, 20], [3, 30], [4, 40]]
let sums = list[a + b foreach a, b in couples]
# Result: list[11, 22, 33, 44]

let pairs = [[2, 5], [3, 4], [10, 10]]
let products = list[a * b foreach a, b in pairs]
# Result: list[10, 12, 100]

String Formatting

let numbers = [1, 2, 3, 4, 5]
let formatted = list["Number: " + str(x) foreach x in numbers]
# Result: list[Number: 1, Number: 2, Number: 3, Number: 4, Number: 5]

Finding Pythagorean Triples

# Find all triples (a, b, c) where a² + b² = c²
let pythag = list[
  [a, b, c]
  foreach a in [1..10]
  foreach b in [a..10]
  foreach c in [b..10]
  when a * a + b * b == c * c
]
# Result: [[3, 4, 5], [6, 8, 10]]

Cartesian Product with Strings

let combinations = list[
  letter + digit
  foreach letter in ["A", "B", "C"]
  foreach digit in ["1", "2", "3"]
]
# Result: list[A1, A2, A3, B1, B2, B3, C1, C2, C3]

Prime Numbers

function isPrime = |n| {
  if n < 2 { return false }
  var i = 2
  while i * i <= n {
    if n % i == 0 { return false }
    i = i + 1
  }
  return true
}

let primes = list[x foreach x in [1..50] when isPrime(x)]
# Result: list[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Functional Operations

Map, Filter, and Reduce

# Map: transform each element
let numbers = list[1, 2, 3, 4, 5]
let doubled = numbers: map(|x| -> x * 2)

# Filter: keep matching elements
let evens = numbers: filter(|x| -> x % 2 == 0)

# Chaining
let result = numbers
  : filter(|x| -> x > 2)
  : map(|x| -> x * 10)

Map vs Comprehension Comparison

# With map()
let result1 = list[1, 2, 3, 4, 5]: map(|x| -> x * 2)

# With comprehension
let result2 = list[x * 2 foreach x in [1, 2, 3, 4, 5]]

# Both produce: list[2, 4, 6, 8, 10]

Patterns and Best Practices

Choosing the Right Collection

Use Case Recommended Collection Reason
Constant data Tuple Guaranteed immutability
Fast index access Array Optimal performance
Functional transformations List Supports map/filter
Numeric data Vector Optimized for numbers
Eliminate duplicates Set Automatic
Key-value pairs Map Appropriate structure

Immutability

# Tuples are immutable
let tuple = [1, 2, 3]
let newTuple = tuple: extend(4, 5)
# tuple remains [1, 2, 3]
# newTuple is [1, 2, 3, 4, 5]

# Arrays are mutable
let arr = array[1, 2, 3]
arr: set(0, 99)
# arr is now array[99, 2, 3]

Performance

Method Chaining

# Readable and expressive
let result = data
  : filter(|x| -> x > 0)
  : map(|x| -> x * 2)
  : filter(|x| -> x < 100)
  : reverse()

Complete Examples

FizzBuzz with Comprehensions

# Find all numbers divisible by both 3 AND 5
let fizzbuzz = list[x foreach x in [1..100] when x % 3 == 0 when x % 5 == 0]
println(fizzbuzz)  # list[15, 30, 45, 60, 75, 90]

Data Transformation Pipeline

let prices = list[10.0, 20.5, 15.75, 30.0, 5.0]

# Apply 20% discount to prices > 10€
let discounted = prices
  : filter(|p| -> p > 10.0)
  : map(|p| -> p * 0.8)

println(discounted)
# list[16.4, 12.6, 24.0]

String Manipulation

let names = list["alice", "bob", "charlie"]

let greetings = names
  : map(|name| -> name: toUpperCase())
  : map(|name| -> "Hello, " + name + "!")

foreach greeting in greetings {
  println(greeting)
}
# Hello, ALICE!
# Hello, BOB!
# Hello, CHARLIE!

© 2026 GoloScript Project | Built with Gu10berg

Subscribe: 📡 RSS | ⚛️ Atom