Skip to main content

Lists

Lists are NumFu's primary data structure for working with collections of values. They're immutable, heterogeneous (can contain different types), and come with powerful operations for transformation and manipulation.


Creating Lists​

List Literals​

Create lists using square brackets with comma-separated elements:

[];                             // Empty list
[1, 2, 3]; // Numbers
["hello", "world"]; // Strings
[true, false, true]; // Booleans
[1, "hello", true]; // Mixed types

Nested Lists​

Lists can contain other lists:

[[1, 2], [3, 4]];               // 2D list
[[], [1], [1, 2]]; // Lists of different lengths
[[[1]], [[2, 3]], [[4, 5, 6]]]; // 3D nested structure

Lists with Expressions​

List elements can be any expressions:

[1 + 2, 3 * 4, 5^2];            // [3, 12, 25]
[sin(0), cos(0), tan(0)]; // [0, 1, 0]

let x = 10 in [x, x*2, x*3]; // [10, 20, 30]

Accessing List Elements​

Indexing​

Access elements using square bracket notation (0-based indexing):

let fruits = ["apple", "banana", "cherry"] in
fruits[0]; // "apple"
// or...
fruits[1]; // "banana"
fruits[2]; // "cherry"

Negative Indexing​

Access elements from the end using negative indices:

let numbers = [10, 20, 30, 40, 50] in
numbers[-1]; // 50 (last element)
// or...
numbers[-2]; // 40 (second to last)

Nested List Access​

Access nested lists by chaining indices:

let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] in
matrix[1][2]; // 6 (row 1, column 2)
// or...
matrix[0][0]; // 1 (top-left)
matrix[2][2]; // 9 (bottom-right)

Index Bounds​

Accessing out-of-bounds indices raises an error:

let short = [1, 2] in
short[5]
// IndexError: List index out of range

List Operations​

Concatenation​

Combine lists using the + operator:

[1, 2] + [3, 4];                // [1, 2, 3, 4]
["a"] + ["b", "c"] + ["d"]; // ["a", "b", "c", "d"]
[] + [1, 2, 3]; // [1, 2, 3]

Repetition​

Repeat lists using the * operator:

[1, 2] * 3;                     // [1, 2, 1, 2, 1, 2]
["hello"] * 2; // ["hello", "hello"]
[1, 2, 3] * 0; // []

List Equality​

Compare lists for equality:

[1, 2, 3] == [1, 2, 3];         // true
[1, 2] == [2, 1]; // false (order matters)
[] == []; // true

Built-in List Functions​

All of these functions must be imported from the std standard library module. When running the examples below, remember to import it at the top of your file (or in the REPL):

import * from "std"

Length​

length([1, 2, 3, 4]);           // 4
length([]); // 0

Adding Elements​

[1, 2, 3] + [4]                 // [1, 2, 3, 4]
append([1, 2, 3], 4); // [1, 2, 3, 4]
append([], "first"); // ["first"]

Element Testing​

contains([1, 2, 3], 2);           // true
contains(["a", "b", "c"], "x"); // false
contains([[], [1], [2]], []); // true

List Transformation​

reverse([1, 2, 3, 4]);          // [4, 3, 2, 1]
reverse([]); // []
reverse(["a", "b", "c"]); // ["c", "b", "a"]

Sorting​

sort([3, 1, 4, 1, 5]);                // [1, 1, 3, 4, 5]
sort(["banana", "apple", "cherry"]); // ["apple", "banana", "cherry"]

Slicing​

Extract sublists using slice(list, start, end):

slice([1, 2, 3, 4, 5], 1, 3);   // [2, 3, 4] (inclusive end)
slice([1, 2, 3, 4, 5], 0, 2); // [1, 2, 3]
slice([1, 2, 3, 4, 5], 2, -2); // [3, 4] (negative index)

Setting Elements​

Create new lists with modified elements:

set([1, 2, 3], 1, 99);          // [1, 99, 3]
set(["a", "b", "c"], 0, "X"); // ["X", "b", "c"]

Functional List Operations​

map - Transform Every Element​

Apply a function to every element in a list:

let numbers = [1, 2, 3, 4, 5] in
let squares = map(numbers, {x -> x * x}) in
squares // [1, 4, 9, 16, 25]

filter - Select Elements​

Keep only elements that satisfy a condition:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] in
let evens = filter(numbers, {x -> x % 2 == 0}) in
evens // [2, 4, 6, 8, 10]

Examples​

When running the examples below, remember to import the std standard library module at the top of your file (or in the REPL) because it provides essential functions for working with lists.

import * from "std"

List Comprehension Style​

While NumFu doesn't have list comprehensions, you can simulate them:

// Generate even squares of numbers 1-10
let range = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] in
filter(map(range, {x -> x * x}), {x -> x % 2 == 0})
// [4, 16, 36, 64, 100]

Matrix Operations​

Sum each row in a matrix​

let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] in
map(matrix, {row ->
let sum = {lst ->
if length(lst) == 0 then 0
else lst[0] + sum(slice(lst, 1, -1))
} in sum(row)
})
// [6, 15, 24]

Flatten a matrix​

let flatten = {lists ->
if length(lists) == 0 then []
else lists[0] + flatten(slice(lists, 1, -1))
} in
flatten([[1, 2], [3, 4], [5, 6]])
// [1, 2, 3, 4, 5, 6]

Transpose a matrix​

let transpose = {matrix ->
if length(matrix) == 0 then []
else
let numCols = length(matrix[0]) in
let getColumn = {col ->
map(matrix, {row -> row[col]})
} in
let range = [0, 1, 2] in // Assuming 3x3 matrix
map(range, getColumn)
} in
transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
// [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Statistics​

Calculate mean of a list​

let mean = {numbers ->
let sum = {lst ->
if length(lst) == 0 then 0
else lst[0] + sum(slice(lst, 1, -1))
} in
sum(numbers) / length(numbers)
} in
mean([10, 20, 30, 40, 50]) // 30

Safe List Access​

// Safe indexing with default values
let safeGet = {lst, index, default ->
if index >= 0 && index < length(lst) then lst[index]
else default
};
safeGet([1, 2, 3], 5, 0); // 0 (default)
safeGet([1, 2, 3], 1, 0); // 2 (actual value)

List Validation​

// Check if all elements satisfy a condition
let allPositive = {numbers ->
length(filter(numbers, {x -> x > 0})) == length(numbers)
};
allPositive([1, 2, 3, 4]); // true
allPositive([1, -2, 3, 4]); // false

List Reduction​

let reduce = {lst, fn, initial ->
if length(lst) == 0 then initial
else reduce(slice(lst, 1, -1), fn, fn(initial, lst[0]))
};
reduce([1, 2, 3, 4], {acc, x -> acc + x}, 0); // 10
reduce([1, 2, 3, 4], {acc, x -> acc * x}, 1); // 24