Variables, Constants and Basic Types

4.1 var, let, const

Every variable is default-initialized (0, 0.0, "", false, nil, @[]).

Nim 2's --experimental:strictDefs and the noinit pragma give more control.

var count = 0          # mutable
count += 1

let name = "Nim"       # immutable after initialization (runtime value)
# name = "x"           # Error

const maxUsers = 100   # compile-time constant (must be computable at compile time)
const greeting = "Hi " & "there"

var
  x, y: int            # default-initialized to 0
  z: float = 1.5

4.2 Primitive Types

int (pointer-size), int8, int16, int32, int64 uint, uint8 (byte), uint16, uint32, uint64

float (= float64), float32, float64 bool (true, false)

char (8-bit), Rune (Unicode, from std/unicode) string (mutable, value semantics, UTF-8 bytes), cstring (C string)

void, pointer, typedesc, untyped, typed (metaprogramming)

4.3 Type Inference and Conversion

Conversions between ints of different sizes are range-checked at runtime in debug builds (RangeDefect).

let a = 42            # int
let b = 42.0          # float
let c = a.float + b   # explicit conversion (no implicit int ↔ float mixing)
let d = int(3.99)     # 3 (truncation)
let e = toInt(3.5)    # 4 (rounding, std/math: round)
let f = $42           # "42" ($ = to string)
echo typeof(c), " ", sizeof(int)

4.4 Integer Overflow and Checks

Overflow raises OverflowDefect in debug mode. Release builds keep checks too. -d:danger disables all runtime checks.

Unsigned types wrap around (no overflow check).

4.5 Ranges and Subranges

type
  Percent = range[0..100]
  Digit = range['0'..'9']
var p: Percent = 50
# p = 150   # compile-time / runtime RangeDefect

4.6 discard

Nim forces you to use return values. Use discard to ignore one explicitly: discard someProc().

{.discardable.} procs can be called without using the result.