structured collections and ordinals
TLDR
- objects, enums and tuples are in userDefinedTypes.nim
- structured types
- can hold multiple values and have unlimited levels of nesting
- two groups
- containers of fields: e.g. objects, tuples, hashtables
- collections of items: e.g. sequences, arrays, char, sub/ranges, tables
- ordinal types
- ordinals are values that can be orderly counted
- enums, u/integers, bool
- are countable and ordered, with a smallest & highest value
- FYI about low & high procs
- should only be used with types not values
links
structured: collections
- cstringArray
array
- list of a static number of items
- similar to C arrays but more memory safety
array procs
- arrayn, T fixed-length dimensionally homogeneous
- array, openArray, UncheckedArray, varargs
- the array size is encoded in its type
- to pass an array to a proc its signature must specify the size and type
- array access is always bounds checked (theres a flag to disable)
- the index type can be any ordinal type
- each array dimension must have the same type,
- nested (multi-dimensional) arrays can have different types than their parent
array like
- openArrayT a procs parameter that accepts an array/seq of any size but only of 1 dimension
- UncheckedArrayT array with no bounds checking for implmenting customized flexibly sized arrays
- varargsT an openarray paramter that accepts a variable number of args in a procedure
table
- syntactic sugar for an array constructor (not to be confused with std/tables!)
- i.e. {"k": "v"} == ("k", "v")
- benefits of table design
- the order of (key,val) are preserved to support ordered dicts
- literals can be a const which requires a minimal amount of memory
- can be efficiently converted to any std/table type
- count table
- hash table
- ordered table
sequence
- seqT dynamic-length dimensionally homogeneous
- always heap allocated & gc'ed
- can be passed to any proc accepting a seq/openarray
- the @ is the array to seq operator: init array and convert to seq
- converting an openArray into a seq is not as efficient as it copies all elements
- or use the newSeq proc
range and alice
- range: a type whose values fall into an arbitrary boundary
- slice: an operator to extract a range from something, usually to pass to a proc
- both use the same syntax, only the context changes
- 0 .. 2 --> inclusive .. inclusive
- 0 .. ^1 --> ^ counts backwards, ^1 includes the last element, ^2 doesnt
range
- rangeT generic constructor for range
- range of values from an ordinal/flaoting-point type
- b0 .. ^1 == b0 .. b.len-1 == b0 ..< b.len
- forward: starts at 0
- backward: start at ^1,
- range of values from an integer or enumeration type
- are checked at runtime whenever the value changes
- valuable for catching / preventing underflows.
- e.g. Nims natural type: type Natural = range0 .. high(int)
- should be used to guard against negative numbers
- you can use Natural.low to check for 0
slice
- provides a range of values matching the type required by the operator/proc
- same syntax as slice but different type (Slice) & context
- collection types define operators/procs which accept slices in place of ranges
- the operator/proc determines the type of values they except in a slice
ordinals
- OrdinalT generic ordinal type
- SomeOrdinal: any int, unit, bool, or enum
generic interface
- should generally work with most types in this file
immutable ops
- a .. ^b Slice: b is a backwardsIndex (inclusive)
- a .. b Slice: inclusive
- a ..< b Slice: excluded upper bound like b == len - 1
- @ Turn an array type into a sequence
- & concat 2 things
- cstringArrayToSeq cstringArray to seqint
- newSeqT create new seq of T with length n into y
- newSeq[T](s: seqT; n) create seq of T with length n, assigned to var s
- newSeqOfCap Create a new sequence with zero length and a given capacity
- newSeqUninitialized only available for number types
- ord(x) returns the integer value that is used to represent x's value
- pred(x, n) opposite of succ, i.e. previous
- succ(x, n) returns the n'th successor of x
- toOpenArray not defined in js targets
- find returns index of thing in item
mutable ops
- add y to collection x
- dec(x, n) decrements x by n; n is an integer
- dec(x) decrements x by one
- del O(1) delete item at index, doesn't preserve the order
- delete Delete an item while preserving the order of elements (O(n) operation)
- grow sets length of X to y
- inc(x, n) increments x by n; n is an integer
- inc(x) increments x by one
- insert Insert an item into container x
- pop Remove and return last item of a sequence
- setLen increase/truncate the length of something
- shrink truncates X to length Y
- swapRefsInArray swaps xN with yN if the elements are refs
inspection ops
- contains true if y is in x, shortcut for find(a, item) => 0
- high (len x) - 1
- high(x) highest possible value/index
- is(x, y) true if value x of type y
- isnot(x,y) opposite of is, equivalent to not(x is type)
- len Return the length
- low(x) lowest possible value/index s
- varargsLen the number of variadic arguments in x
- in/notin
set
- see deepdives/collections.nim for sets (hash set)
- setT generic set constructor
- collection of distinct ordinal values
- basetype must be of int8/16, uint8/16, byte, char, enum
- hash sets (import std/sets) dont have this restriction
- implemented as high performance bit vectors
- often used to provide flags for procs
set operators
- a - b Difference
- A - B difference of two sets (A without B's elements)
- A * B intersection of two sets
- A + B union of two sets
- a < b Check if a is a subset of b
- A < B strict subset relation (A is a proper subset of B)
- A <= B subset relation (A is subset of B or equal to B)
- A == B set equality
- e in A set membership (A contains element e)
- e notin A A does not contain element e
set procs
- card(A) the cardinality of A (number of elements in A)
- excl(A, elem) same as A = A - {elem}
- incl(A, elem) same as A = A + {elem}