Slices in Nim

import sequtils, strformat

proc main() =
  # Sequences are Nim's equivalent to Go's slices.
  # An uninitialized sequence is empty and has length 0.
  var s: seq[string]
  echo fmt"uninit: {s}, {s == @[]}, {len(s) == 0}"

  # To create an empty sequence with non-zero length, use
  # the newSeq procedure. Here we make a sequence of
  # strings of length 3 (initially empty strings).
  s = newSeq[string](3)
  echo fmt"emp: {s}, len: {len(s)}, cap: {s.len}"

  # We can set and get just like with arrays.
  s[0] = "a"
  s[1] = "b"
  s[2] = "c"
  echo fmt"set: {s}"
  echo fmt"get: {s[2]}"

  # len returns the length of the sequence as expected.
  echo fmt"len: {len(s)}"

  # In addition to these basic operations, sequences
  # support several more that make them richer than
  # arrays. One is the add procedure, which
  # adds one or more new values to the sequence.
  s.add("d")
  s.add("e")
  s.add("f")
  echo fmt"add: {s}"

  # Sequences can also be copied. Here we create a new
  # sequence c and copy the contents of s into it.
  var c = s
  echo fmt"cpy: {c}"

  # Sequences support slicing with the syntax
  # sequence[low..high]. For example, this gets a slice
  # of the elements s[2], s[3], and s[4].
  var l = s[2..4]
  echo fmt"sl1: {l}"

  # This slices up to (but excluding) s[5].
  l = s[0..4]
  echo fmt"sl2: {l}"

  # And this slices up from (and including) s[2].
  l = s[2..^1]
  echo fmt"sl3: {l}"

  # We can declare and initialize a variable for sequence
  # in a single line as well.
  let t = @["g", "h", "i"]
  echo fmt"dcl: {t}"

  # Nim's standard library contains a number of useful
  # utility functions for sequences.
  let t2 = @["g", "h", "i"]
  if t == t2:
    echo "t == t2"

  # Sequences can be composed into multi-dimensional data
  # structures. The length of the inner sequences can
  # vary, unlike with multi-dimensional arrays.
  var twoD = newSeq[seq[int]](3)
  for i in 0..2:
    let innerLen = i + 1
    twoD[i] = newSeq[int](innerLen)
    for j in 0..<innerLen:
      twoD[i][j] = i + j

  echo fmt"2d: {twoD}"

main()

To run the program, save it as sequences.nim and use the Nim compiler:

$ nim c -r sequences.nim
uninit: @[], true, true
emp: @["", "", ""], len: 3, cap: 3
set: @["a", "b", "c"]
get: c
len: 3
add: @["a", "b", "c", "d", "e", "f"]
cpy: @["a", "b", "c", "d", "e", "f"]
sl1: @["c", "d", "e"]
sl2: @["a", "b", "c", "d", "e"]
sl3: @["c", "d", "e", "f"]
dcl: @["g", "h", "i"]
t == t2
2d: @[@[0], @[1, 2], @[2, 3, 4]]

Note that while sequences in Nim are similar to slices in Go, there are some differences in syntax and available operations. Nim uses @[] for sequence literals and seq[T] for sequence types. The add procedure is used instead of append, and slicing syntax is slightly different. Nim’s standard library provides many utility functions for working with sequences, similar to Go’s slices package.