Sakura Lang

Update list indices with List.set

Reassign the new list returned by `List.set` while preserving earlier versions.

Generated by cargo run -p agent_docs from compiler/examples/. Edit the example files, then regenerate.

Reassign the new list returned by List.set while preserving earlier versions.

Collections have value semantics. List.set(values, index, value) returns a new list; ignoring the result leaves values unchanged. The loop computes the length once, handles empty input, then uses the half-open range 0..n. Every read and write is in bounds because replacement preserves length. An external index needs both the nonnegative and upper-bound checks, as replace_if_present demonstrates.

The tests check changed values, the unchanged original list, empty and singleton inputs, and external indices below zero, at the length and inside the list. The harness also runs main and checks [3, 0, 7, 0]. No effects other than its console output, permissions or slice/concat reconstruction are needed.

Source project · harness mode: run + test.

From the repository root, with this checkout's sakura on PATH:

cd compiler/examples/indexed_update
sakura check --json
sakura run
sakura test --json

Manifest and permissions

[package]
name = "indexed_update"
version = "0.1.0"
edition = "2026"

[permissions]

Source and tests

src/main.sakura includes all required imports and tests.

// milestone: M3
// mode: run
// spec: design §17.145

fn replace_negatives(values: List<Int>) -> List<Int> {
  var updated = values
  let n = List.len(updated)
  if n == 0 { return updated }
  for i in 0..n {
    let value = List.get(updated, i).expect("i is inside the half-open range")
    if value < 0 { updated = List.set(updated, i, 0) }
  }
  updated
}

pub fn main() -> Unit ! {Console} { Console.print("{replace_negatives([3, -2, 7, -1])}") }

test "updates preserve earlier versions" {
  let original = [3, -2, 7, -1]
  expect_eq(replace_negatives(original), [3, 0, 7, 0])
  expect_eq(original, [3, -2, 7, -1])
}

test "empty, singleton and unchanged inputs" {
  expect_eq(replace_negatives([]), [])
  expect_eq(replace_negatives([-1]), [0])
  expect_eq(replace_negatives([0, 4]), [0, 4])
}

fn replace_if_present(values: List<Int>, index: Int, value: Int) -> List<Int> {
  if index >= 0 && index < List.len(values) { List.set(values, index, value) } else { values }
}

test "external indices are checked before replacement" {
  expect_eq(replace_if_present([7], -1, 9), [7])
  expect_eq(replace_if_present([7], 1, 9), [7])
  expect_eq(replace_if_present([], 0, 9), [])
  expect_eq(replace_if_present([7], 0, 9), [9])
}

Expected stdout

[3, 0, 7, 0]

Compiler provenance and regeneration

These eight projects teach supported Sakura APIs on the JavaScript backend. Each project is exercised offline by cargo test -p sakura_cli --test examples; HTTP and LLM exchanges are synthetic committed cassettes, with no network or API keys. Use Node 26 for execution, including its built-in SQLite implementation.

The initial API baseline is compiler revision 5cae349516c21714d90d36e87f1cfd6debe980c6. CI reruns these projects against the compiler in the same checkout. Build that checkout's CLI and run sakura --version and sakura prompt before adapting a recipe; pre-alpha APIs can change. An installed skill's frontmatter records its compiler version and build revision. These teaching examples are separate from the agent evaluation tasks.

The source of each page is its example's recipe.md, sakura.toml, src/main.sakura and fixture files. Run cargo run -p agent_docs from compiler/ to regenerate the cookbook and skill reference. Edit those sources, not the rendered pages.

Edit on GitHub

On this page