The compiler depends on the System module to work properly and the System module depends on the compiler. Most of the routines listed here use special compiler magic.
Each module implicitly imports the System module; it must not be listed explicitly. Because of this there cannot be a user-defined module named system.
The System module imports several separate modules, and their documentation is in separate files:
Here is a short overview of the most commonly used functions from the system module. Function names in the tables below are clickable and will take you to the full documentation of the function.
There are many more functions available than the ones listed in this overview. Use the table of contents on the left-hand side and/or Ctrl+F to navigate through this module.
| Proc | Usage |
|---|---|
| len(s) | Return the length of a string |
| chr(i) | Convert an int in the range 0..255 to a character |
| ord(c) | Return int value of a character |
| a & b | Concatenate two strings |
| s.add(c) | Add character to the string |
| $ | Convert various types to string |
See also:
scanf and scanp macros, which offer easier substring extraction than regular expressions| Proc | Usage |
|---|---|
| newSeq | Create a new sequence of a given length |
| newSeqOfCap | Create a new sequence with zero length and a given capacity |
| setLen | Set the length of a sequence |
| len | Return the length of a sequence |
| @ | Turn an array into a sequence |
| add | Add an item to the sequence |
| insert | Insert an item at a specific position |
| delete | Delete an item while preserving the order of elements (O(n) operation) |
| del |
O(1) removal, doesn't preserve the order |
| pop | Remove and return last item of a sequence |
| x & y | Concatenate two sequences |
| x[a .. b] | Slice of a sequence (both ends included) |
| x[a .. ^b] | Slice of a sequence but b is a reversed index (both ends included) |
| x[a ..< b] | Slice of a sequence (excluded upper bound) |
See also:
Built-in bit sets.
| Proc | Usage |
|---|---|
| incl | Include element y in the set x
|
| excl | Exclude element y from the set x
|
| card | Return the cardinality of the set, i.e. the number of elements |
| a * b | Intersection |
| a + b | Union |
| a - b | Difference |
| contains | Check if an element is in the set |
| a < b | Check if a is a subset of b
|
See also:
| Proc | Usage | Also known as (in other languages) |
|---|---|---|
| div | Integer division | // |
| mod | Integer modulo (remainder) | % |
| shl | Shift left | << |
| shr | Shift right | >> |
| ashr | Arithmetic shift right | |
| and | Bitwise and
|
& |
| or | Bitwise or
|
| |
| xor | Bitwise xor
|
^ |
| not | Bitwise not (complement) |
~ |
| toInt | Convert floating-point number into an int
|
|
| toFloat | Convert an integer into a float
|
See also:
Ordinal type includes integer, bool, character, and enumeration types, as well as their subtypes.
| Proc | Usage |
|---|---|
| succ | Successor of the value |
| pred | Predecessor of the value |
| inc | Increment the ordinal |
| dec | Decrement the ordinal |
| high | Return the highest possible value |
| low | Return the lowest possible value |
| ord | Return int value of an ordinal value |
| Proc | Usage |
|---|---|
| is | Check if two arguments are of the same type |
| isnot | Negated version of is
|
| != | Not equals |
| addr | Take the address of a memory location |
| T and F | Boolean and
|
| T or F | Boolean or
|
| T xor F | Boolean xor (exclusive or) |
| not T | Boolean not
|
| a[^x] | Take the element at the reversed index x
|
| a .. b | Binary slice that constructs an interval [a, b]
|
| a ..^ b | Interval [a, b] but b as reversed index |
| a ..< b | Interval [a, b) (excluded upper bound) |
| runnableExamples | Create testable documentation |
Channel support for threads.
Note: This is part of the system module. Do not import it directly. To activate thread support compile with the --threads:on command line switch.
Note: Channels are designed for the Thread type. They are unstable when used with spawn
Note: The current implementation of message passing does not work with cyclic data structures.
Note: Channels cannot be passed between threads. Use globals or pass them by ptr.
The following is a simple example of two different ways to use channels: blocking and non-blocking.
# Be sure to compile with --threads:on.
# The channels and threads modules are part of system and should not be
# imported.
import std/os
# Channels can either be:
# - declared at the module level, or
# - passed to procedures by ptr (raw pointer) -- see note on safety.
#
# For simplicity, in this example a channel is declared at module scope.
# Channels are generic, and they include support for passing objects between
# threads.
# Note that objects passed through channels will be deeply copied.
var chan: Channel[string]
# This proc will be run in another thread using the threads module.
proc firstWorker() =
chan.send("Hello World!")
# This is another proc to run in a background thread. This proc takes a while
# to send the message since it sleeps for 2 seconds (or 2000 milliseconds).
proc secondWorker() =
sleep(2000)
chan.send("Another message")
# Initialize the channel.
chan.open()
# Launch the worker.
var worker1: Thread[void]
createThread(worker1, firstWorker)
# Block until the message arrives, then print it out.
echo chan.recv() # "Hello World!"
# Wait for the thread to exit before moving on to the next example.
worker1.joinThread()
# Launch the other worker.
var worker2: Thread[void]
createThread(worker2, secondWorker)
# This time, use a non-blocking approach with tryRecv.
# Since the main thread is not blocked, it could be used to perform other
# useful work while it waits for data to arrive on the channel.
while true:
let tried = chan.tryRecv()
if tried.dataAvailable:
echo tried.msg # "Another message"
break
echo "Pretend I'm doing useful work..."
# For this example, sleep in order not to flood stdout with the above
# message.
sleep(400)
# Wait for the second thread to exit before cleaning up the channel.
worker2.joinThread()
# Clean up the channel.
chan.close() The program should output something similar to this, but keep in mind that exact results may vary in the real world:
Hello World! Pretend I'm doing useful work... Pretend I'm doing useful work... Pretend I'm doing useful work... Pretend I'm doing useful work... Pretend I'm doing useful work... Another message
Note that when passing objects to procedures on another thread by pointer (for example through a thread's argument), objects created using the default allocator will use thread-local, GC-managed memory. Thus it is generally safer to store channel objects in global variables (as in the above example), in which case they will use a process-wide (thread-safe) shared heap.
However, it is possible to manually allocate shared memory for channels using e.g. system.allocShared0 and pass these pointers through thread arguments:
proc worker(channel: ptr Channel[string]) =
let greeting = channel[].recv()
echo greeting
proc localChannelExample() =
# Use allocShared0 to allocate some shared-heap memory and zero it.
# The usual warnings about dealing with raw pointers apply. Exercise caution.
var channel = cast[ptr Channel[string]](
allocShared0(sizeof(Channel[string]))
)
channel[].open()
# Create a thread which will receive the channel as an argument.
var thread: Thread[ptr Channel[string]]
createThread(thread, worker, channel)
channel[].send("Hello from the main thread!")
# Clean up resources.
thread.joinThread()
channel[].close()
deallocShared(channel)
localChannelExample() # "Hello from the main thread!" any {....deprecated: "Deprecated since v1.5; Use auto instead.".} = distinct autoauto instead. See https://github.com/nim-lang/RFCs/issues/281 Source Edit BackwardsIndex = distinct int
^ for reversed array accesses. (See ^ template) Source Edit CatchableError = object of Exception
csize {.importc: "size_t", nodecl, ...deprecated: "use `csize_t` instead".} = intsize_t in C. Don't use it. Source Edit Defect = object of Exception
quit / trap / exit operation. Source Edit Endianness = enum littleEndian, bigEndian
Exception {.compilerproc, magic: "Exception".} = object of RootObj
parent*: ref Exception ## Parent exception (can be used as a stack).
name*: cstring ## The exception's name is its Nim identifier.
## This field is filled automatically in the
## `raise` statement.
msg* {.exportc: "message".}: string ## The exception's message. Not
## providing an exception message
## is bad style.
when defined(js):
trace*: string
else:
trace*: seq[StackTraceEntry]Base exception class.
Each exception has to inherit from Exception. See the full exception hierarchy.
ForLoopStmt {.compilerproc.} = objectGC_Strategy = enum gcThroughput, ## optimize for throughput gcResponsiveness, ## optimize for responsiveness (default) gcOptimizeTime, ## optimize for speed gcOptimizeSpace ## optimize for memory footprint
HSlice[T; U] = object a*: T ## The lower bound (inclusive). b*: U ## The upper bound (inclusive).
int {.magic: Int.}Natural = range[0 .. high(int)]
int type ranging from zero to the maximum value of an int. This type is often useful for documentation and debugging. Source Edit NimNode {.magic: "PNimrodNode".} = ref NimNodeObjopenArray[T] {.magic: "OpenArray".}Ordinal[T] {.magic: Ordinal.}SomeOrdinal. Source Edit owned[T] {.magic: "BuiltinType".}owned. Source Edit PFrame = ptr TFrame
pointer {.magic: Pointer.}addr operator to get a pointer to a variable. Source Edit Positive = range[1 .. high(int)]
int type ranging from one to the maximum value of an int. This type is often useful for documentation and debugging. Source Edit RootEffect {.compilerproc.} = object of RootObjBase effect class.
Each effect should inherit from RootEffect unless you know what you're doing.
RootObj {.compilerproc, inheritable.} = objectThe root of Nim's object hierarchy.
Objects should inherit from RootObj or one of its descendants. However, objects that have no ancestor are also allowed.
SomeFloat = float | float32 | float64
SomeOrdinal = int | int8 | int16 | int32 | int64 | bool | enum | uint | uint8 |
uint16 |
uint32 |
uint64Ordinal Source Edit SomeSignedInt = int | int8 | int16 | int32 | int64
SomeUnsignedInt = uint | uint8 | uint16 | uint32 | uint64
StackTraceEntry = object
procname*: cstring ## Name of the proc that is currently executing.
line*: int ## Line number of the proc that is currently executing.
filename*: cstring ## Filename of the proc that is currently executing.
when NimStackTraceMsgs:
frameMsg*: string ## When a stacktrace is generated in a given frame and
## rendered at a later time, we should ensure the stacktrace
## data isn't invalidated; any pointer into PFrame is
## subject to being invalidated so shouldn't be stored.
when defined(nimStackTraceOverride):
programCounter*: uint ## Program counter - will be used to get the rest of the info,
## when `$` is called on this type. We can't use
## "cuintptr_t" in here.
procnameStr*, filenameStr*: string ## GC-ed alternatives to "procname" and "filename"StackTraceEntry is a single entry of the stack trace. Source Edit static[T] {.magic: "Static".}Meta type representing all values that can be evaluated at compile-time.
The type coercion static(x) can be used to force the compile-time evaluation of the given expression x.
TFrame {.importc, nodecl, final.} = object
prev*: PFrame ## Previous frame; used for chaining the call stack.
procname*: cstring ## Name of the proc that is currently executing.
line*: int ## Line number of the proc that is currently executing.
filename*: cstring ## Filename of the proc that is currently executing.
len*: int16 ## Length of the inspectable slots.
calldepth*: int16 ## Used for max call depth checking.
when NimStackTraceMsgs:
frameMsgLen*: int ## end position in frameMsgBuf for this frame.type[T] {.magic: "Type".}Meta type representing the type of all type values.
The coercion type(x) can be used to obtain the type of the given expression x.
typed {.magic: Stmt.}TypeOfMode = enum typeOfProc, ## Prefer the interpretation that means `x` is a proc call. typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
typeof. Source Edit errorMessageWriter: (proc (msg: string) {....tags: [WriteIOEffect], gcsafe, nimcall.})stdmsg.write when printing stacktrace. Unstable API. Source Edit globalRaiseHook: proc (e: ref Exception): bool {.nimcall, ...gcsafe.}If globalRaiseHook returns false, the exception is caught and does not propagate further through the call stack.
localRaiseHook {.threadvar.}: proc (e: ref Exception): bool {.nimcall, ...gcsafe.}If localRaiseHook returns false, the exception is caught and does not propagate further through the call stack.
nimThreadDestructionHandlers {.threadvar.}: seq[
proc () {.closure, ...gcsafe, raises: [].}]onUnhandledException: (proc (errorMsg: string) {.nimcall, ...gcsafe.})Set this error handler to override the existing behaviour on an unhandled exception.
The default is to write a stacktrace to stderr and then call quit(1). Unstable API.
outOfMemHook: proc () {.nimcall, ...tags: [], gcsafe, raises: [].}Set this variable to provide a procedure that should be called in case of an out of memory event. The standard handler writes an error message and terminates the program.
outOfMemHook can be used to raise an exception in case of OOM like so:
var gOutOfMem: ref EOutOfMemory new(gOutOfMem) # need to be allocated *before* OOM really happened! gOutOfMem.msg = "out of memory" proc handleOOM() = raise gOutOfMem system.outOfMemHook = handleOOM
If the handler does not raise an exception, ordinary control flow continues and the program is terminated.
Source EditprogramResult {.compilerproc, exportc: "nim_program_result".}: intquit or exitprocs.getProgramResult, exitprocs.setProgramResult. Source Edit unhandledExceptionHook: proc (e: ref Exception) {.nimcall, ...tags: [], gcsafe,
raises: [].}unhandle exception event. The standard handler writes an error message and terminates the program, except when using --os:any Source Edit appType {.magic: "AppType".}: string = """console", "gui", "lib". Source Edit CompileDate {.magic: "CompileDate".}: string = "0000-00-00"YYYY-MM-DD. This works thanks to compiler magic. Source Edit CompileTime {.magic: "CompileTime".}: string = "00:00:00"HH:MM:SS. This works thanks to compiler magic. Source Edit cpuEndian {.magic: "CpuEndian".}: Endianness = littleEndianhostCPU {.magic: "HostCPU".}: string = ""A string that describes the host CPU.
Possible values: "i386", "alpha", "powerpc", "powerpc64", "powerpc64el", "sparc", "amd64", "mips", "mipsel", "arm", "arm64", "mips64", "mips64el", "riscv32", "riscv64", "loongarch64".
hostOS {.magic: "HostOS".}: string = ""A string that describes the host operating system.
Possible values: "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", "aix", "haiku", "standalone".
Inf = 0x7FF0000000000000'f64
isMainModule {.magic: "IsMainModule".}: bool = falseNaN = 0x7FF7FFFFFFFFFFFF'f64
Contains an IEEE floating point value of Not A Number.
Note that you cannot compare a floating point value to this value and expect a reasonable result - use the isNaN or classify procedure in the math module for checking for NaN.
NegInf = 0xFFF0000000000000'f64
NimMajor {.intdefine.}: int = 2is the major number of Nim's version. Example:
when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discardSource Edit
NimMinor {.intdefine.}: int = 2proc `&`(x, y: char): string {.magic: "ConStrStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}Concatenates characters x and y into a string.
assert('a' & 'b' == "ab") Source Edit proc `&`(x, y: string): string {.magic: "ConStrStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}Concatenates strings x and y.
assert("ab" & "cd" == "abcd") Source Edit proc `&`(x: char; y: string): string {.magic: "ConStrStr", noSideEffect,
...raises: [], tags: [], forbids: [].}Concatenates x with y.
assert('a' & "bc" == "abc") Source Edit proc `&`(x: string; y: char): string {.magic: "ConStrStr", noSideEffect,
...raises: [], tags: [], forbids: [].}Concatenates x with y.
assert("ab" & 'c' == "abc") Source Edit proc `&`[T](x, y: sink seq[T]): seq[T] {.noSideEffect.}Concatenates two sequences.
Requires copying of the sequences.
assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6])
See also:
Source Editproc `*`(x, y: float): float {.magic: "MulF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: float32): float32 {.magic: "MulF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: int): int {.magic: "MulI", noSideEffect, ...raises: [], tags: [],
forbids: [].}* operator for an integer. Source Edit proc `*`(x, y: int8): int8 {.magic: "MulI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `*`(x, y: int16): int16 {.magic: "MulI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: int32): int32 {.magic: "MulI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: int64): int64 {.magic: "MulI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: uint): uint {.magic: "MulU", noSideEffect, ...raises: [], tags: [],
forbids: [].}* operator for unsigned integers. Source Edit proc `*`(x, y: uint8): uint8 {.magic: "MulU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: uint16): uint16 {.magic: "MulU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `*`(x, y: uint32): uint32 {.magic: "MulU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: float): float {.magic: "AddF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: float32): float32 {.magic: "AddF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: int): int {.magic: "AddI", noSideEffect, ...raises: [], tags: [],
forbids: [].}+ operator for an integer. Source Edit proc `+`(x, y: int8): int8 {.magic: "AddI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `+`(x, y: int16): int16 {.magic: "AddI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: int32): int32 {.magic: "AddI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: int64): int64 {.magic: "AddI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: uint): uint {.magic: "AddU", noSideEffect, ...raises: [], tags: [],
forbids: [].}+ operator for unsigned integers. Source Edit proc `+`(x, y: uint8): uint8 {.magic: "AddU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: uint16): uint16 {.magic: "AddU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: uint32): uint32 {.magic: "AddU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x, y: uint64): uint64 {.magic: "AddU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x: float): float {.magic: "UnaryPlusF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x: int): int {.magic: "UnaryPlusI", noSideEffect, ...raises: [], tags: [],
forbids: [].}+ operator for an integer. Has no effect. Source Edit proc `+`(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `+`(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: float): float {.magic: "SubF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: float32): float32 {.magic: "SubF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: int): int {.magic: "SubI", noSideEffect, ...raises: [], tags: [],
forbids: [].}- operator for an integer. Source Edit proc `-`(x, y: int8): int8 {.magic: "SubI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `-`(x, y: int16): int16 {.magic: "SubI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: int32): int32 {.magic: "SubI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: int64): int64 {.magic: "SubI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: uint): uint {.magic: "SubU", noSideEffect, ...raises: [], tags: [],
forbids: [].}- operator for unsigned integers. Source Edit proc `-`(x, y: uint8): uint8 {.magic: "SubU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: uint16): uint16 {.magic: "SubU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: uint32): uint32 {.magic: "SubU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x, y: uint64): uint64 {.magic: "SubU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x: float): float {.magic: "UnaryMinusF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x: float32): float32 {.magic: "UnaryMinusF64", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `-`(x: int): int {.magic: "UnaryMinusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}- operator for an integer. Negates x. Source Edit proc `-`(x: int8): int8 {.magic: "UnaryMinusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x: int16): int16 {.magic: "UnaryMinusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `-`(x: int32): int32 {.magic: "UnaryMinusI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `..`[T, U](a: sink T; b: sink U): HSlice[T, U] {.noSideEffect, inline,
magic: "DotDot", ...raises: [], tags: [], forbids: [].}Binary slice operator that constructs an interval [a, b], both a and b are inclusive.
Slices can also be used in the set constructor and in ordinal case statements, but then they are special-cased by the compiler.
let a = [10, 20, 30, 40, 50] echo a[2 .. 3] # @[30, 40]Source Edit
proc `/`(x, y: float): float {.magic: "DivF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`(x, y: bool): bool {.magic: "LtB", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: char): bool {.magic: "LtCh", noSideEffect, ...raises: [], tags: [],
forbids: [].}x is lexicographically before y (uppercase letters come before lowercase letters). Example:
let a = 'a' b = 'b' c = 'Z' assert a < b assert not (a < a) assert not (a < c)Source Edit
proc `<`(x, y: float): bool {.magic: "LtF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`(x, y: float32): bool {.magic: "LtF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`(x, y: int): bool {.magic: "LtI", noSideEffect, ...raises: [], tags: [],
forbids: [].}x is less than y. Source Edit proc `<`(x, y: int8): bool {.magic: "LtI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: int16): bool {.magic: "LtI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: int32): bool {.magic: "LtI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: int64): bool {.magic: "LtI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: pointer): bool {.magic: "LtPtr", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`(x, y: string): bool {.magic: "LtStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}x is lexicographically before y (uppercase letters come before lowercase letters). Example:
let a = "abc" b = "abd" c = "ZZZ" assert a < b assert not (a < a) assert not (a < c)Source Edit
proc `<`(x, y: uint): bool {.magic: "LtU", noSideEffect, ...raises: [], tags: [],
forbids: [].}x < y. Source Edit proc `<`(x, y: uint8): bool {.magic: "LtU", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: uint16): bool {.magic: "LtU", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: uint32): bool {.magic: "LtU", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`(x, y: uint64): bool {.magic: "LtU", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<`[Enum: enum](x, y: Enum): bool {.magic: "LtEnum", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `<`[T: tuple](x, y: T): bool
< operator for tuples that is lifted from the components of x and y. This implementation uses cmp. Source Edit proc `<`[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<`[T](x, y: set[T]): bool {.magic: "LtSet", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns true if x is a strict or proper subset of y.
A strict or proper subset x has all of its members in y but y has more elements than y.
Example:
let
a = {3, 5}
b = {1, 3, 5, 7}
c = {2}
assert a < b
assert not (a < a)
assert not (a < c) Source Edit proc `<=`(x, y: bool): bool {.magic: "LeB", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: char): bool {.magic: "LeCh", noSideEffect, ...raises: [], tags: [],
forbids: [].}x is lexicographically before y (uppercase letters come before lowercase letters). Example:
let a = 'a' b = 'b' c = 'Z' assert a <= b assert a <= a assert not (a <= c)Source Edit
proc `<=`(x, y: float): bool {.magic: "LeF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`(x, y: float32): bool {.magic: "LeF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`(x, y: int): bool {.magic: "LeI", noSideEffect, ...raises: [], tags: [],
forbids: [].}x is less than or equal to y. Source Edit proc `<=`(x, y: int8): bool {.magic: "LeI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: int16): bool {.magic: "LeI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: int32): bool {.magic: "LeI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: int64): bool {.magic: "LeI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: pointer): bool {.magic: "LePtr", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`(x, y: string): bool {.magic: "LeStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}x is lexicographically before y (uppercase letters come before lowercase letters). Example:
let a = "abc" b = "abd" c = "ZZZ" assert a <= b assert a <= a assert not (a <= c)Source Edit
proc `<=`(x, y: uint): bool {.magic: "LeU", noSideEffect, ...raises: [], tags: [],
forbids: [].}x <= y. Source Edit proc `<=`(x, y: uint8): bool {.magic: "LeU", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `<=`(x, y: uint16): bool {.magic: "LeU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`(x, y: uint32): bool {.magic: "LeU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`(x, y: uint64): bool {.magic: "LeU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`[Enum: enum](x, y: Enum): bool {.magic: "LeEnum", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `<=`[T: tuple](x, y: T): bool
<= operator for tuples that is lifted from the components of x and y. This implementation uses cmp. Source Edit proc `<=`[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `<=`[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns true if x is a subset of y.
A subset x has all of its members in y and y doesn't necessarily have more members than x. That is, x can be equal to y.
Example:
let
a = {3, 5}
b = {1, 3, 5, 7}
c = {2}
assert a <= b
assert a <= a
assert not (a <= c) Source Edit proc `==`(x, y: bool): bool {.magic: "EqB", noSideEffect, ...raises: [], tags: [],
forbids: [].}bool variables. Source Edit proc `==`(x, y: char): bool {.magic: "EqCh", noSideEffect, ...raises: [], tags: [],
forbids: [].}char variables. Source Edit proc `==`(x, y: cstring): bool {.magic: "EqCString", noSideEffect, inline,
...raises: [], tags: [], forbids: [].}cstring variables. Source Edit proc `==`(x, y: float): bool {.magic: "EqF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `==`(x, y: float32): bool {.magic: "EqF64", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `==`(x, y: int): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: int8): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: int16): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: int32): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: int64): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: pointer): bool {.magic: "EqRef", noSideEffect, ...raises: [],
tags: [], forbids: [].}pointer variables. Example:
var # this is a wildly dangerous example a = cast[pointer](0) b = cast[pointer](nil) assert a == b # true due to the special meaning of `nil`/0 as a pointerSource Edit
proc `==`(x, y: string): bool {.magic: "EqStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}string variables. Source Edit proc `==`(x, y: uint): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: uint8): bool {.magic: "EqI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc `==`(x, y: uint16): bool {.magic: "EqI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `==`(x, y: uint32): bool {.magic: "EqI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `==`(x, y: uint64): bool {.magic: "EqI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `==`[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect,
...raises: [], tags: [], forbids: [].}Example:
type
Enum1 = enum
field1 = 3, field2
Enum2 = enum
place1, place2 = 3
var
e1 = field1
e2 = place2.ord.Enum1
assert e1 == e2
assert not compiles(e1 == place2) # raises error Source Edit proc `==`[T: proc | iterator](x, y: T): bool {.magic: "EqProc", noSideEffect,
...raises: [], tags: [], forbids: [].}proc variables refer to the same procedure. Source Edit proc `==`[T: tuple | object](x, y: T): bool
== operator for tuples that is lifted from the components. of x and y. Source Edit proc `==`[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect, ...raises: [],
tags: [], forbids: [].}ptr variables refer to the same item. Source Edit proc `==`[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect, ...raises: [],
tags: [], forbids: [].}ref variables refer to the same item. Source Edit proc `=destroy`(x: string) {.inline, magic: "Destroy", enforceNoRaises,
...raises: [], tags: [], forbids: [].}proc `=destroy`[T](x: ref T) {.inline, magic: "Destroy", ...raises: [], tags: [],
forbids: [].}proc `@`[IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq",
noSideEffect, ...raises: [], tags: [], forbids: [].}Turns an array into a sequence.
This most often useful for constructing sequences with the array constructor: @[1, 2, 3] has the type seq[int], while [1, 2, 3] has the type array[0..2, int].
let a = [1, 3, 5] b = "foo" echo @a # => @[1, 3, 5] echo @b # => @['f', 'o', 'o']Source Edit
proc `[]`(s: string; i: BackwardsIndex): char {.inline, systemRaisesDefect,
...raises: [], tags: [], forbids: [].}proc `[]`(s: var string; i: BackwardsIndex): var char {.inline,
systemRaisesDefect, ...raises: [], tags: [], forbids: [].}proc `[]`[I: Ordinal; T](a: T; i: I): T {.noSideEffect, magic: "ArrGet",
...raises: [], tags: [], forbids: [].}proc `[]`[Idx, T; U, V: Ordinal](a: array[Idx, T]; x: HSlice[U, V]): seq[T] {.
systemRaisesDefect.}Slice operation for arrays. Returns the inclusive range [a[x.a], a[x.b]]:
var a = [1, 2, 3, 4] assert a[0..2] == @[1, 2, 3]
See also:
Source Editproc `[]`[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline,
systemRaisesDefect.}proc `[]`[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline,
systemRaisesDefect.}proc `[]`[T, U: Ordinal](s: string; x: HSlice[T, U]): string {.inline,
systemRaisesDefect.}Slice operation for strings. Returns the inclusive range [s[x.a], s[x.b]]:
var s = "abcdef" assert s[1..3] == "bcd"Source Edit
proc `[]=`(s: var string; i: BackwardsIndex; x: char) {.inline,
systemRaisesDefect, ...raises: [], tags: [], forbids: [].}proc `[]=`[I: Ordinal; T, S](a: T; i: I; x: sink S) {.noSideEffect,
magic: "ArrPut", ...raises: [], tags: [], forbids: [].}proc `[]=`[Idx, T; U, V: Ordinal](a: var array[Idx, T]; x: HSlice[U, V];
b: openArray[T]) {.systemRaisesDefect.}Slice assignment for arrays.
var a = [10, 20, 30, 40, 50] a[1..2] = @[99, 88] assert a == [10, 99, 88, 40, 50]Source Edit
proc `[]=`[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline,
systemRaisesDefect.}proc `[]=`[T, U: Ordinal](s: var string; x: HSlice[T, U]; b: string) {.
systemRaisesDefect.}Slice assignment for strings.
If b.len is not exactly the number of elements that are referred to by x, a splice is performed:
Example:
var s = "abcdefgh" s[1 .. ^2] = "xyz" assert s == "axyzh"Source Edit
proc `[]=`[T; U, V: Ordinal](s: var seq[T]; x: HSlice[U, V]; b: openArray[T]) {.
systemRaisesDefect.}Slice assignment for sequences.
If b.len is not exactly the number of elements that are referred to by x, a splice is performed.
Example:
var s = @"abcdefgh" s[1 .. ^2] = @"xyz" assert s == @"axyzh"Source Edit
func abs(x: int16): int16 {.magic: "AbsI", inline, ...raises: [], tags: [],
forbids: [].}func abs(x: int32): int32 {.magic: "AbsI", inline, ...raises: [], tags: [],
forbids: [].}proc add(x: var cstring; y: cstring) {.magic: "AppendStrStr", ...raises: [],
tags: [], forbids: [].}y to x in place. Only implemented for JS backend. Example:
when defined(js):
var tmp: cstring = ""
tmp.add(cstring("ab"))
tmp.add(cstring("cd"))
doAssert tmp == cstring("abcd") Source Edit proc add(x: var string; y: char) {.magic: "AppendStrCh", noSideEffect,
...raises: [], tags: [], forbids: [].}Appends y to x in place.
var tmp = ""
tmp.add('a')
tmp.add('b')
assert(tmp == "ab") Source Edit proc add(x: var string; y: cstring) {.asmNoStackFrame, ...raises: [], tags: [],
forbids: [].}y to x in place. Example:
var tmp = ""
tmp.add(cstring("ab"))
tmp.add(cstring("cd"))
doAssert tmp == "abcd" Source Edit proc add(x: var string; y: string) {.magic: "AppendStrStr", noSideEffect,
...raises: [], tags: [], forbids: [].}Concatenates x and y in place.
See also strbasics.add.
Example:
var tmp = ""
tmp.add("ab")
tmp.add("cd")
assert tmp == "abcd" Source Edit proc add[T](x: var seq[T]; y: openArray[T]) {.noSideEffect.}Generic proc for adding a container y to a container x.
For containers that have an order, add means append. New generic containers should also call their adding proc add for consistency. Generic code becomes much easier to write if the Nim naming scheme is respected.
See also:
Example:
var a = @["a1", "a2"] a.add(["b1", "b2"]) assert a == @["a1", "a2", "b1", "b2"] var c = @["c0", "c1", "c2", "c3"] a.add(c.toOpenArray(1, 2)) assert a == @["a1", "a2", "b1", "b2", "c1", "c2"]Source Edit
proc add[T](x: var seq[T]; y: sink T) {.magic: "AppendSeqElem", noSideEffect,
nodestroy, ...raises: [], tags: [],
forbids: [].}Generic proc for adding a data item y to a container x.
For containers that have an order, add means append. New generic containers should also call their adding proc add for consistency. Generic code becomes much easier to write if the Nim naming scheme is respected.
proc addEscapedChar(s: var string; c: char) {.noSideEffect, inline, ...raises: [],
tags: [], forbids: [].}s and applies the following escaping:\ by \\
' by \'
" by \"
\a by \\a
\b by \\b
\t by \\t
\n by \\n
\v by \\v
\f by \\f
\r by \\r
\e by \\e
{\21..\126} by \xHH where HH is its hexadecimal valueThe procedure has been designed so that its output is usable for many different common syntaxes.
proc addQuitProc(quitProc: proc () {.noconv.}) {.importc: "atexit",
header: "<stdlib.h>", ...deprecated: "use exitprocs.addExitProc", raises: [],
tags: [], forbids: [].}Adds/registers a quit procedure.
Each call to addQuitProc registers another quit procedure. Up to 30 procedures can be registered. They are executed on a last-in, first-out basis (that is, the last function registered is the first to be executed). addQuitProc raises an EOutOfIndex exception if quitProc cannot be registered.
proc addQuoted[T](s: var string; x: T)
Appends x to string s in place, applying quoting and escaping if x is a string or char.
See addEscapedChar for the escaping scheme. When x is a string, characters in the range {\128..\255} are never escaped so that multibyte UTF-8 characters are untouched (note that this behavior is different from addEscapedChar).
The Nim standard library uses this function on the elements of collections when producing a string representation of a collection. It is recommended to use this function as well for user-side collections. Users may overload addQuoted for custom (string-like) types if they want to implement a customized element representation.
var tmp = ""
tmp.addQuoted(1)
tmp.add(", ")
tmp.addQuoted("string")
tmp.add(", ")
tmp.addQuoted('c')
assert(tmp == """1, "string", 'c'""") Source Edit proc `addr`[T](x: T): ptr T {.magic: "Addr", noSideEffect, ...raises: [], tags: [],
forbids: [].}addr operator for taking the address of a memory location.let variables or parameters for better interop with C. When you use it to write a wrapper for a C library and take the address of let variables or parameters, you should always check that the original library does never write to data behind the pointer that is returned from this procedure.Cannot be overloaded.
var buf: seq[char] = @['a','b','c'] p = buf[1].addr echo p.repr # ref 0x7faa35c40059 --> 'b' echo p[] # bSource Edit
proc `and`(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect,
...raises: [], tags: [], forbids: [].}and meta class. Source Edit proc `and`(x, y: bool): bool {.magic: "And", noSideEffect, ...raises: [], tags: [],
forbids: [].}Boolean and; returns true if x == y == true (if both arguments are true).
Evaluation is lazy: if x is false, y will not even be evaluated.
proc `and`(x, y: int): int {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise and of numbers x and y. Example:
assert (0b0011 and 0b0101) == 0b0001 assert (0b0111 and 0b1100) == 0b0100Source Edit
proc `and`(x, y: int8): int8 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `and`(x, y: int16): int16 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `and`(x, y: int32): int32 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `and`(x, y: int64): int64 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `and`(x, y: uint): uint {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise and of numbers x and y. Source Edit proc `and`(x, y: uint8): uint8 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `and`(x, y: uint16): uint16 {.magic: "BitandI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc ashr(x: int8; y: SomeInteger): int8 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc ashr(x: int16; y: SomeInteger): int16 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc ashr(x: int32; y: SomeInteger): int32 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc ashr(x: int64; y: SomeInteger): int64 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc ashr(x: int; y: SomeInteger): int {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}Shifts right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off.
Note that ashr is not an operator so use the normal function call syntax for it.
See also:
Example:
assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8 assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8 assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8Source Edit
func chr(u: range[0 .. 255]): char {.magic: "Chr", ...raises: [], tags: [],
forbids: [].}u to a char, same as char(u). Example:
doAssert chr(65) == 'A' doAssert chr(255) == '\255' doAssert chr(255) == char(255) doAssert not compiles chr(256) doAssert not compiles char(256) var x = 256 doAssertRaises(RangeDefect): discard chr(x) doAssertRaises(RangeDefect): discard char(x)Source Edit
proc clamp[T](x, a, b: T): T
x within the interval [a, b]. This proc is equivalent to but faster than max(a, min(b, x)).a <= b is assumed and will not be checked (currently).See also: math.clamp for a version that takes a Slice[T] instead.
Example:
assert (1.4).clamp(0.0, 1.0) == 1.0 assert (0.5).clamp(0.0, 1.0) == 0.5 assert 4.clamp(1, 3) == max(1, min(3, 4))Source Edit
proc cmp(x, y: string): int {.noSideEffect, ...raises: [], tags: [], forbids: [].}Compare proc for strings. More efficient than the generic version.
Note: The precise result values depend on the used C runtime library and can differ between operating systems!
Source Editproc cmp[T](x, y: T): int
Generic compare proc.
Returns:
x < y
x > y
x == y
This is useful for writing generic algorithms without performance loss. This generic implementation uses the == and < operators.
import std/algorithm echo sorted(@[4, 2, 6, 5, 8, 7], cmp[int])Source Edit
proc cmpMem(a, b: pointer; size: Natural): int {.inline, noSideEffect, ...tags: [],
raises: [], forbids: [].}Compares the memory blocks a and b. size bytes will be compared.
Returns:
a < b
a > b
a == b
Like any procedure dealing with raw memory this is unsafe.
Source Editproc compileOption(option, arg: string): bool {.magic: "CompileOptionArg",
noSideEffect, ...raises: [], tags: [], forbids: [].}Can be used to determine an enum compile-time option.
See also:
on|off optionsExample:
when compileOption("opt", "size") and compileOption("gc", "boehm"):
discard "compiled with optimization for size and uses Boehm's GC" Source Edit proc compileOption(option: string): bool {.magic: "CompileOption", noSideEffect,
...raises: [], tags: [], forbids: [].}Can be used to determine an on|off compile-time option.
See also:
Example: cmd: --floatChecks:off
static: doAssert not compileOption("floatchecks")
{.push floatChecks: on.}
static: doAssert compileOption("floatchecks")
# floating point NaN and Inf checks enabled in this scope
{.pop.} Source Edit proc compiles(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime,
...raises: [], tags: [], forbids: [].}Special compile-time procedure that checks whether x can be compiled without any semantic error. This can be used to check whether a type supports some operation:
when compiles(3 + 4): echo "'+' for integers is available"Source Edit
proc contains[T](a: openArray[T]; item: T): bool {.inline.}Returns true if item is in a or false if not found. This is a shortcut for find(a, item) >= 0.
This allows the in operator: a.contains(item) is the same as item in a.
var a = @[1, 3, 5] assert a.contains(5) assert 3 in a assert 99 notin aSource Edit
func contains[T](x: set[T]; y: T): bool {.magic: "InSet", ...raises: [], tags: [],
forbids: [].}One should overload this proc if one wants to overload the in operator.
The parameters are in reverse order! a in b is a template for contains(b, a). This is because the unification algorithm that Nim uses for overload resolution works from left to right. But for the in operator that would be the wrong direction for this piece of code:
Example:
var s: set[range['a'..'z']] = {'a'..'c'}
assert s.contains('c')
assert 'b' in s
assert 'd' notin s
assert set['a'..'z'] is set[range['a'..'z']]If in had been declared as [T](elem: T, s: set[T]) then T would have been bound to char. But s is not compatible to type set[char]! The solution is to bind T to range['a'..'z']. This is achieved by reversing the parameters for contains; in then passes its arguments in reverse order. Source Edit proc copyMem(dest, source: pointer; size: Natural) {.inline, ...gcsafe, tags: [],
raises: [], forbids: [].}source to the memory at dest. Exactly size bytes will be copied. The memory regions may not overlap. Like any procedure dealing with raw memory this is unsafe. Source Edit proc create(T: typedesc; size = 1.Positive): ptr T:type {.inline, ...gcsafe,
raises: [].}Allocates a new memory block with at least T.sizeof * size bytes.
The block has to be freed with resize(block, 0) or dealloc(block). The block is initialized with all bytes containing zero, so it is somewhat safer than createU.
The allocated memory belongs to its allocating thread! Use createShared to allocate from a shared heap.
Source Editproc createU(T: typedesc; size = 1.Positive): ptr T:type {.inline, ...gcsafe,
raises: [].}Allocates a new memory block with at least T.sizeof * size bytes.
The block has to be freed with resize(block, 0) or dealloc(block). The block is not initialized, so reading from it before writing to it is undefined behaviour!
The allocated memory belongs to its allocating thread! Use createSharedU to allocate from a shared heap.
See also:
Source Editproc dealloc(p: pointer) {.noconv, compilerproc, ...gcsafe, gcsafe, raises: [],
tags: [], forbids: [].}Frees the memory allocated with alloc, alloc0, realloc, create or createU.
This procedure is dangerous! If one forgets to free the memory a leak occurs; if one tries to access freed memory (or just freeing it twice!) a core dump may happen or other memory may be corrupted.
The freed memory must belong to its allocating thread! Use deallocShared to deallocate from a shared heap.
Source Editproc debugEcho(x: varargs[typed, `$`]) {.magic: "Echo", noSideEffect, ...tags: [],
raises: [], forbids: [].}debugEcho pretends to be free of side effects, so that it can be used for debugging routines marked as noSideEffect. Source Edit proc dec[T, V: Ordinal](x: var T; y: V = 1) {.magic: "Dec", noSideEffect,
...raises: [], tags: [], forbids: [].}Decrements the ordinal x by y.
If such a value does not exist, OverflowDefect is raised or a compile time error occurs. This is a short notation for: x = pred(x, y).
Example:
var i = 2 dec(i) assert i == 1 dec(i, 3) assert i == -2Source Edit
proc declared(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime,
...raises: [], tags: [], forbids: [].}Special compile-time procedure that checks whether x is declared. x has to be an identifier or a qualified identifier.
This can be used to check whether a library provides a certain feature or not:
when not declared(strutils.toUpper): # provide our own toUpper proc here, because strutils is # missing it.
See also:
Source Editproc deepCopy[T](x: var T; y: T) {.noSideEffect, magic: "DeepCopy", ...raises: [],
tags: [], forbids: [].}Performs a deep copy of y and copies it into x.
This is also used by the code generator for the implementation of spawn.
For --mm:arc or --mm:orc deepcopy support has to be enabled via --deepcopy:on.
proc default[T](_: typedesc[T]): T {.magic: "Default", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns the default value of the type T. Contrary to zeroDefault, it takes default fields of an object into consideration.
See also:
Example: cmd: -d:nimPreviewRangeDefault
assert (int, float).default == (0, 0.0) type Foo = object a: range[2..6] var x = Foo.default assert x.a == 2Source Edit
proc defined(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime,
...raises: [], tags: [], forbids: [].}Special compile-time procedure that checks whether x is defined.
x is an external symbol introduced through the compiler's -d:x switch to enable build time conditionals:
when not defined(release): # Do here programmer friendly expensive sanity checks. # Put here the normal code
See also:
on|off optionsproc delete[T](x: var seq[T]; i: Natural) {.noSideEffect, systemRaisesDefect.}Deletes the item at index i by moving all x[i+1..^1] items by one position.
This is an O(n) operation.
See also:
Example:
var s = @[1, 2, 3, 4, 5] s.delete(2) doAssert s == @[1, 2, 4, 5]Source Edit
proc `div`(x, y: int): int {.magic: "DivI", noSideEffect, ...raises: [], tags: [],
forbids: [].}Computes the integer division.
This is roughly the same as math.trunc(x/y).int.
Example:
assert (1 div 2) == 0 assert (2 div 2) == 1 assert (3 div 2) == 1 assert (7 div 3) == 2 assert (-7 div 3) == -2 assert (7 div -3) == -2 assert (-7 div -3) == 2Source Edit
proc `div`(x, y: int8): int8 {.magic: "DivI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `div`(x, y: int16): int16 {.magic: "DivI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `div`(x, y: int32): int32 {.magic: "DivI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `div`(x, y: int64): int64 {.magic: "DivI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `div`(x, y: uint): uint {.magic: "DivU", noSideEffect, ...raises: [],
tags: [], forbids: [].}trunc(x/y). Source Edit proc `div`(x, y: uint8): uint8 {.magic: "DivU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `div`(x, y: uint16): uint16 {.magic: "DivU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc echo(x: varargs[typed, `$`]) {.magic: "Echo", ...gcsafe, sideEffect,
...raises: [], tags: [], forbids: [].}Writes and flushes the parameters to the standard output.
Special built-in that takes a variable number of arguments. Each argument is converted to a string via $, so it works for user-defined types that have an overloaded $ operator. It is roughly equivalent to writeLine(stdout, x); flushFile(stdout), but available for the JavaScript target too.
Unlike other IO operations this is guaranteed to be thread-safe as echo is very often used for debugging convenience. If you want to use echo inside a proc without side effects you can use debugEcho instead.
proc equalMem(a, b: pointer; size: Natural): bool {.inline, noSideEffect,
...tags: [], raises: [], forbids: [].}Compares the memory blocks a and b. size bytes will be compared.
If the blocks are equal, true is returned, false otherwise. Like any procedure dealing with raw memory this is unsafe.
proc getTypeInfo[T](x: T): pointer {.magic: "GetTypeInfo", ...gcsafe, raises: [],
tags: [], forbids: [].}Get type information for x.
Ordinary code should not use this, but the typeinfo module instead.
Source Editproc gorge(command: string; input = ""; cache = ""): string {.
magic: "StaticExec", ...raises: [], tags: [], forbids: [].}proc high(x: cstring): int {.magic: "High", noSideEffect, ...raises: [], tags: [],
forbids: [].}Returns the highest possible index of a compatible string x. This is sometimes an O(n) operation.
See also:
Source Editproc high(x: string): int {.magic: "High", noSideEffect, ...raises: [], tags: [],
forbids: [].}Returns the highest possible index of a string x.
var str = "Hello world!" high(str) # => 11
See also:
Source Editproc high[I, T](x: array[I, T]): I {.magic: "High", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns the highest possible index of an array x.
For empty arrays, the return type is int.
var arr = [1, 2, 3, 4, 5, 6, 7] high(arr) # => 6 for i in low(arr)..high(arr): echo arr[i]
See also:
Source Editproc high[I, T](x: typedesc[array[I, T]]): I {.magic: "High", noSideEffect,
...raises: [], tags: [], forbids: [].}Returns the highest possible index of an array type.
For empty arrays, the return type is int.
high(array[7, int]) # => 6
See also:
Source Editproc high[T: Ordinal | enum | range](x: T): T {.magic: "High", noSideEffect, ...deprecated: "Deprecated since v1.4; there should not be `high(value)`. Use `high(type)`.",
raises: [], tags: [], forbids: [].}Returns the highest possible value of an ordinal value x.
As a special semantic rule, x may also be a type identifier.
This proc is deprecated, use this one instead:
high(2) # => 9223372036854775807Source Edit
proc high[T: Ordinal | enum | range](x: typedesc[T]): T {.magic: "High",
noSideEffect, ...raises: [], tags: [], forbids: [].}Returns the highest possible value of an ordinal or enum type.
high(int) is Nim's way of writing INT_MAX or MAX_INT.
high(int) # => 9223372036854775807
See also:
Source Editproc inc[T, V: Ordinal](x: var T; y: V = 1) {.magic: "Inc", noSideEffect,
...raises: [], tags: [], forbids: [].}Increments the ordinal x by y.
If such a value does not exist, OverflowDefect is raised or a compile time error occurs. This is a short notation for: x = succ(x, y).
Example:
var i = 2 inc(i) assert i == 3 inc(i, 3) assert i == 6Source Edit
proc instantiationInfo(index = -1; fullPaths = false): tuple[filename: string,
line: int, column: int] {.magic: "InstantiationInfo", noSideEffect,
...raises: [], tags: [], forbids: [].}Provides access to the compiler's instantiation stack line information of a template.
While similar to the caller info of other languages, it is determined at compile time.
This proc is mostly useful for meta programming (eg. assert template) to retrieve information about the current filename and line number. Example:
import std/strutils
template testException(exception, code: untyped): typed =
try:
let pos = instantiationInfo()
discard(code)
echo "Test failure at $1:$2 with '$3'" % [pos.filename,
$pos.line, astToStr(code)]
assert false, "A test expecting failure succeeded?"
except exception:
discard
proc tester(pos: int): int =
let
a = @[1, 2, 3]
result = a[pos]
when isMainModule:
testException(IndexDefect, tester(30))
testException(IndexDefect, tester(1))
# --> Test failure at example.nim:20 with 'tester(1)' Source Edit proc `is`[T, S](x: T; y: S): bool {.magic: "Is", noSideEffect, ...raises: [],
tags: [], forbids: [].}Checks if T is of the same type as S.
For a negated version, use isnot.
assert 42 is int
assert @[1, 2] is seq
proc test[T](a: T): int =
when (T is int):
return a
else:
return 0
assert(test[int](3) == 3)
assert(test[string]("xyz") == 0) Source Edit proc isNil(x: cstring): bool {.noSideEffect, magic: "IsNil", ...raises: [],
tags: [], forbids: [].}proc isNil(x: pointer): bool {.noSideEffect, magic: "IsNil", ...raises: [],
tags: [], forbids: [].}proc isNil[T: proc | iterator {.closure.}](x: T): bool {.noSideEffect,
magic: "IsNil", ...raises: [], tags: [], forbids: [].}x is nil. This is sometimes more efficient than == nil. Source Edit proc isUniqueRef[T](x: ref T): bool {.inline.}x points to is uniquely referenced. Such an object can potentially be passed over to a different thread safely, if great care is taken. This queries the internal reference count of the object which is subject to lots of optimizations! In other words the value of isUniqueRef can depend on the used compiler version and optimizer setting. Nevertheless it can be used as a very valuable debugging tool and can be used to specify the constraints of a threading related API via assert isUniqueRef(x). Source Edit func len(x: (type array) | array): int {.magic: "LengthArray", ...raises: [],
tags: [], forbids: [].}high(T)-low(T)+1. Example:
var a = [1, 1, 1] assert a.len == 3 assert array[0, float].len == 0 static: assert array[-2..2, float].len == 5Source Edit
proc len(x: cstring): int {.magic: "LengthStr", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns the length of a compatible string. This is an O(n) operation except in js at runtime.
Note: On the JS backend this currently counts UTF-16 code points instead of bytes at runtime (not at compile time). For now, if you need the byte length of the UTF-8 encoding, convert to string with $ first then call len.
Example:
doAssert len(cstring"abc") == 3 doAssert len(cstring r"ab\0c") == 5 # \0 is escaped doAssert len(cstring"ab\0c") == 5 # ditto var a: cstring = "ab\0c" when defined(js): doAssert a.len == 4 # len ignores \0 for js else: doAssert a.len == 2 # \0 is a null terminator static: var a2: cstring = "ab\0c" doAssert a2.len == 2 # \0 is a null terminator, even in js vmSource Edit
func len(x: string): int {.magic: "LengthStr", ...raises: [], tags: [], forbids: [].}Example:
assert "abc".len == 3 assert "".len == 0 assert string.default.len == 0Source Edit
func len[T](x: seq[T]): int {.magic: "LengthSeq", ...raises: [], tags: [],
forbids: [].}x. Example:
assert @[0, 1].len == 2 assert seq[int].default.len == 0 assert newSeq[int](3).len == 3 let s = newSeqOfCap[int](3) assert s.len == 0Source Edit
func len[T](x: set[T]): int {.magic: "Card", ...raises: [], tags: [], forbids: [].}card(x). Source Edit proc locals(): RootObj {.magic: "Plugin", noSideEffect, ...raises: [], tags: [],
forbids: [].}Generates a tuple constructor expression listing all the local variables in the current scope.
This is quite fast as it does not rely on any debug or runtime information. Note that in contrast to what the official signature says, the return type is not RootObj but a tuple of a structure that depends on the current scope. Example:
proc testLocals() =
var
a = "something"
b = 4
c = locals()
d = "super!"
b = 1
for name, value in fieldPairs(c):
echo "name ", name, " with value ", value
echo "B is ", b
# -> name a with value something
# -> name b with value 4
# -> B is 1 Source Edit proc low(x: cstring): int {.magic: "Low", noSideEffect, ...raises: [], tags: [],
forbids: [].}Returns the lowest possible index of a compatible string x.
See also:
Source Editproc low(x: string): int {.magic: "Low", noSideEffect, ...raises: [], tags: [],
forbids: [].}Returns the lowest possible index of a string x.
var str = "Hello world!" low(str) # => 0
See also:
Source Editproc low[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect, ...raises: [],
tags: [], forbids: [].}Returns the lowest possible index of an array x.
For empty arrays, the return type is int.
var arr = [1, 2, 3, 4, 5, 6, 7] low(arr) # => 0 for i in low(arr)..high(arr): echo arr[i]
See also:
Source Editproc low[I, T](x: typedesc[array[I, T]]): I {.magic: "Low", noSideEffect,
...raises: [], tags: [], forbids: [].}Returns the lowest possible index of an array type.
For empty arrays, the return type is int.
low(array[7, int]) # => 0
See also:
Source Editproc low[T: Ordinal | enum | range](x: T): T {.magic: "Low", noSideEffect, ...deprecated: "Deprecated since v1.4; there should not be `low(value)`. Use `low(type)`.",
raises: [], tags: [], forbids: [].}Returns the lowest possible value of an ordinal value x. As a special semantic rule, x may also be a type identifier.
This proc is deprecated, use this one instead:
low(2) # => -9223372036854775808Source Edit
proc low[T: Ordinal | enum | range](x: typedesc[T]): T {.magic: "Low",
noSideEffect, ...raises: [], tags: [], forbids: [].}Returns the lowest possible value of an ordinal or enum type.
low(int) is Nim's way of writing INT_MIN or MIN_INT.
low(int) # => -9223372036854775808
See also:
Source Editproc max(x, y: float32): float32 {.noSideEffect, inline, ...raises: [], tags: [],
forbids: [].}proc max(x, y: float64): float64 {.noSideEffect, inline, ...raises: [], tags: [],
forbids: [].}proc max(x, y: int): int {.magic: "MaxI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc max(x, y: int8): int8 {.magic: "MaxI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc max(x, y: int16): int16 {.magic: "MaxI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc max(x, y: int32): int32 {.magic: "MaxI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc max(x, y: int64): int64 {.magic: "MaxI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc min(x, y: float32): float32 {.noSideEffect, inline, ...raises: [], tags: [],
forbids: [].}proc min(x, y: float64): float64 {.noSideEffect, inline, ...raises: [], tags: [],
forbids: [].}proc min(x, y: int): int {.magic: "MinI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc min(x, y: int8): int8 {.magic: "MinI", noSideEffect, ...raises: [], tags: [],
forbids: [].}proc min(x, y: int16): int16 {.magic: "MinI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc min(x, y: int32): int32 {.magic: "MinI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc min(x, y: int64): int64 {.magic: "MinI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: int): int {.magic: "ModI", noSideEffect, ...raises: [], tags: [],
forbids: [].}Computes the integer modulo operation (remainder).
This is the same as x - (x div y) * y.
Example:
assert (7 mod 5) == 2 assert (-7 mod 5) == -2 assert (7 mod -5) == 2 assert (-7 mod -5) == -2Source Edit
proc `mod`(x, y: int8): int8 {.magic: "ModI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: int16): int16 {.magic: "ModI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: int32): int32 {.magic: "ModI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: int64): int64 {.magic: "ModI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: uint): uint {.magic: "ModU", noSideEffect, ...raises: [],
tags: [], forbids: [].}x - (x div y) * y. Source Edit proc `mod`(x, y: uint8): uint8 {.magic: "ModU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `mod`(x, y: uint16): uint16 {.magic: "ModU", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc moveMem(dest, source: pointer; size: Natural) {.inline, ...gcsafe, tags: [],
raises: [], forbids: [].}Copies the contents from the memory at source to the memory at dest.
Exactly size bytes will be copied. The memory regions may overlap, moveMem handles this case appropriately and is thus somewhat more safe than copyMem. Like any procedure dealing with raw memory this is still unsafe, though.
proc new(t: typedesc): auto
Creates a new object of type T and returns a safe (traced) reference to it as result value.
When T is a ref type then the resulting type will be T, otherwise it will be ref T.
proc new[T](a: var ref T) {.magic: "New", noSideEffect, ...raises: [], tags: [],
forbids: [].}T and returns a safe (traced) reference to it in a. Source Edit proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.}) {.
magic: "NewFinalize", noSideEffect, ...raises: [], tags: [], forbids: [].}Creates a new object of type T and returns a safe (traced) reference to it in a.
When the garbage collector frees the object, finalizer is called. The finalizer may not keep a reference to the object pointed to by x. The finalizer cannot prevent the GC from freeing the object.
Note: The finalizer refers to the type T, not to the object! This means that for each object of type T the finalizer will be called!
proc newSeq[T](len = 0.Natural): seq[T]
Creates a new sequence of type seq[T] with length len.
Note that the sequence will be filled with zeroed entries. After the creation of the sequence you should assign entries to the sequence instead of adding them.
var inputStrings = newSeq[string](3) assert len(inputStrings) == 3 inputStrings[0] = "The fourth" inputStrings[1] = "assignment" inputStrings[2] = "would crash" #inputStrings[3] = "out of bounds"
See also:
Source Editproc newSeq[T](s: var seq[T]; len: Natural) {.magic: "NewSeq", noSideEffect,
...raises: [], tags: [], forbids: [].}Creates a new sequence of type seq[T] with length len.
This is equivalent to s = @[]; setlen(s, len), but more efficient since no reallocation is needed.
Note that the sequence will be filled with zeroed entries. After the creation of the sequence you should assign entries to the sequence instead of adding them. Example:
var inputStrings: seq[string] newSeq(inputStrings, 3) assert len(inputStrings) == 3 inputStrings[0] = "The fourth" inputStrings[1] = "assignment" inputStrings[2] = "would crash" #inputStrings[3] = "out of bounds"Source Edit
func newSeqUninit[T](len: Natural): seq[T]
Creates a new sequence of type seq[T] with length len.
Only available for types, which don't contain managed memory or have destructors. Note that the sequence will be uninitialized. After the creation of the sequence you should assign entries to the sequence instead of adding them.
Example:
var x = newSeqUninit[int](3) assert len(x) == 3 x[0] = 10Source Edit
proc newSeqUninitialized[T: SomeNumber](len: Natural): seq[T] {.
...deprecated: "Use `newSeqUninit` instead".}Creates a new sequence of type seq[T] with length len.
Only available for numbers types. Note that the sequence will be uninitialized. After the creation of the sequence you should assign entries to the sequence instead of adding them. Example:
var x = newSeqUninitialized[int](3) assert len(x) == 3 x[0] = 10Source Edit
proc newString(len: Natural): string {.magic: "NewString",
importc: "mnewString", noSideEffect,
...raises: [], tags: [], forbids: [].}Returns a new string of length len. One needs to fill the string character after character with the index operator s[i].
This procedure exists only for optimization purposes; the same effect can be achieved with the & operator or with add.
proc newStringOfCap(cap: Natural): string {.magic: "NewStringOfCap",
importc: "rawNewString", noSideEffect, ...raises: [], tags: [], forbids: [].}Returns a new string of length 0 but with capacity cap.
This procedure exists only for optimization purposes; the same effect can be achieved with the & operator or with add.
proc newStringUninit(len: Natural): string {....raises: [], tags: [], forbids: [].}Returns a new string of length len but with uninitialized content. One needs to fill the string character after character with the index operator s[i].
This procedure exists only for optimization purposes; the same effect can be achieved with the & operator or with add.
proc `not`(a: typedesc): typedesc {.magic: "TypeTrait", noSideEffect,
...raises: [], tags: [], forbids: [].}not meta class. Source Edit proc `not`(x: bool): bool {.magic: "Not", noSideEffect, ...raises: [], tags: [],
forbids: [].}x == false. Source Edit proc `not`(x: int): int {.magic: "BitnotI", noSideEffect, ...raises: [], tags: [],
forbids: [].}bitwise complement of the integer x. Example:
assert not 0'u8 == 255 assert not 0'i8 == -1 assert not 1000'u16 == 64535 assert not 1000'i16 == -1001Source Edit
proc `not`(x: int8): int8 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `not`(x: int16): int16 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `not`(x: int32): int32 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `not`(x: int64): int64 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `not`(x: uint): uint {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise complement of the integer x. Source Edit proc `not`(x: uint8): uint8 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `not`(x: uint16): uint16 {.magic: "BitnotI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `of`[T, S](x: T; y: typedesc[S]): bool {.magic: "Of", noSideEffect,
...raises: [], tags: [], forbids: [].}x is an instance of y. Example:
type Base = ref object of RootObj Sub1 = ref object of Base Sub2 = ref object of Base Unrelated = ref object var base: Base = Sub1() # downcast doAssert base of Base # generates `CondTrue` (statically true) doAssert base of Sub1 doAssert base isnot Sub1 doAssert not (base of Sub2) base = Sub2() # re-assign doAssert base of Sub2 doAssert Sub2(base) != nil # upcast doAssertRaises(ObjectConversionDefect): discard Sub1(base) var sub1 = Sub1() doAssert sub1 of Base doAssert sub1.Base of Sub1 doAssert not compiles(base of Unrelated)Source Edit
proc onThreadDestruction(handler: proc () {.closure, ...gcsafe, raises: [].}) {.
...raises: [], tags: [], forbids: [].}Registers a thread local handler that is called at the thread's destruction.
A thread is destructed when the .thread proc returns normally or when it raises an exception. Note that unhandled exceptions in a thread nevertheless cause the whole process to die.
proc `or`(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect,
...raises: [], tags: [], forbids: [].}or meta class. Source Edit proc `or`(x, y: bool): bool {.magic: "Or", noSideEffect, ...raises: [], tags: [],
forbids: [].}Boolean or; returns true if not (not x and not y) (if any of the arguments is true).
Evaluation is lazy: if x is true, y will not even be evaluated.
proc `or`(x, y: int): int {.magic: "BitorI", noSideEffect, ...raises: [], tags: [],
forbids: [].}bitwise or of numbers x and y. Example:
assert (0b0011 or 0b0101) == 0b0111 assert (0b0111 or 0b1100) == 0b1111Source Edit
proc `or`(x, y: int8): int8 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `or`(x, y: int16): int16 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `or`(x, y: int32): int32 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `or`(x, y: int64): int64 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `or`(x, y: uint): uint {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise or of numbers x and y. Source Edit proc `or`(x, y: uint8): uint8 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `or`(x, y: uint16): uint16 {.magic: "BitorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}func ord[T: Ordinal | enum](x: T): int {.magic: "Ord", ...raises: [], tags: [],
forbids: [].}int value of x, including for enum with holes and distinct ordinal types. Example:
assert ord('A') == 65
type Foo = enum
f0 = 0, f1 = 3
assert f1.ord == 3
type Bar = distinct int
assert 3.Bar.ord == 3 Source Edit proc peek[TMsg](c: var Channel[TMsg]): int
Returns the current number of messages in the channel c.
Returns -1 if the channel has been closed.
Note: This is dangerous to use as it encourages races. It's much better to use tryRecv proc instead.
Source Editproc pop[T](s: var seq[T]): T {.inline, noSideEffect.}Returns the last item of s and decreases s.len by one. This treats s as a stack and implements the common pop operation.
Raises IndexDefect if s is empty.
Example:
var a = @[1, 3, 5, 7] let b = pop(a) assert b == 7 assert a == @[1, 3, 5]Source Edit
proc pred[T, V: Ordinal](x: T; y: V = 1): T {.magic: "Pred", noSideEffect,
...raises: [], tags: [], forbids: [].}Returns the y-th predecessor (default: 1) of the value x.
If such a value does not exist, OverflowDefect is raised or a compile time error occurs.
Example:
assert pred(5) == 4 assert pred(5, 3) == 2Source Edit
proc quit(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn, ...raises: [],
tags: [], forbids: [].}Stops the program immediately with an exit code.
Before stopping the program the "exit procedures" are called in the opposite order they were added with addExitProc.
The proc quit(QuitSuccess) is called implicitly when your nim program finishes without incident for platforms where this is the expected behavior. A raised unhandled exception is equivalent to calling quit(QuitFailure).
Note that this is a runtime call and using quit inside a macro won't have any compile time effect. If you need to stop the compiler inside a macro, use the error or fatal pragmas.
errorcode gets saturated when it exceeds the valid range on the specific platform. On Posix, the valid range is low(int8)..high(int8). On Windows, the valid range is low(int32)..high(int32). For instance, quit(int(0x100000000)) is equal to quit(127) on Linux.raiseAssert or raise a Defect. quit bypasses regular control flow in particular defer, try, catch, finally and destructors, and exceptions that may have been raised by an addExitProc proc, as well as cleanup code in other threads. It does not call the garbage collector to free all the memory, unless an addExitProc proc calls GC_fullCollect.proc rawProc[T: proc {.closure.} | iterator {.closure.}](x: T): pointer {.
noSideEffect, inline.}x. This is useful for interfacing closures with C/C++, hash computations, etc. If rawEnv(x) returns nil, the proc which the result points to takes as many parameters as x, but with {.nimcall.} as its calling convention instead of {.closure.}, otherwise it takes one more parameter which is a pointer, and it still has {.nimcall.} as its calling convention. To invoke the resulted proc, what this returns has to be casted into a proc, not a ptr proc, and, in a case where rawEnv(x) returns non-nil, the last and additional argument has to be the result of rawEnv(x). This is not available for the JS target. Example:
proc makeClosure(x: int): (proc(y: int): int) =
var n = x
result = (
proc(y: int): int =
n += y
return n
)
var
c1 = makeClosure(10)
e = c1.rawEnv()
p = c1.rawProc()
if e.isNil():
let c2 = cast[proc(y: int): int {.nimcall.}](p)
echo c2(2)
else:
let c3 = cast[proc(y: int; env: pointer): int {.nimcall.}](p)
echo c3(3, e) Source Edit proc resize[T](p: ptr T; newSize: Natural): ptr T {.inline, ...gcsafe, raises: [].}Grows or shrinks a given memory block.
If p is nil then a new memory block is returned. In either way the block has at least T.sizeof * newSize bytes. If newSize == 0 and p is not nil resize calls dealloc(p). In other cases the block has to be freed with free.
The allocated memory belongs to its allocating thread! Use resizeShared to reallocate from a shared heap.
Source Editproc runnableExamples(rdoccmd = ""; body: untyped) {.magic: "RunnableExamples",
...raises: [], tags: [], forbids: [].}runnableExamples section is ignored.## doc comment. As the last step of documentation generation each runnableExample is put in its own file $file_examples$i.nim, compiled and tested. The collected examples are put into their own module to ensure the examples do not refer to non-exported symbols.Example:
proc timesTwo*(x: int): int =
## This proc doubles a number.
runnableExamples:
# at module scope
const exported* = 123
assert timesTwo(5) == 10
block: # at block scope
defer: echo "done"
runnableExamples "-d:foo -b:cpp":
import std/compilesettings
assert querySetting(backend) == "cpp"
assert defined(foo)
runnableExamples "-r:off": ## this one is only compiled
import std/browsers
openDefaultBrowser "https://forum.nim-lang.org/"
2 * x Source Edit proc setControlCHook(hook: proc () {.noconv.}) {....raises: [], tags: [],
forbids: [].}Allows you to override the behaviour of your application when CTRL+C is pressed. Only one such hook is supported. Example:
proc ctrlc() {.noconv.} =
echo "Ctrl+C fired!"
# do clean up stuff
quit()
setControlCHook(ctrlc) Source Edit proc setLen(s: var string; newlen: Natural) {.magic: "SetLengthStr",
noSideEffect, ...raises: [], tags: [], forbids: [].}Sets the length of string s to newlen.
If the current length is greater than the new length, s will be truncated.
var myS = "Nim is great!!" myS.setLen(3) # myS <- "Nim" echo myS, " is fantastic!!"Source Edit
proc setLen[T](s: var seq[T]; newlen: Natural) {.magic: "SetLengthSeq",
noSideEffect, nodestroy, ...raises: [], tags: [], forbids: [].}Sets the length of seq s to newlen. T may be any sequence type.
If the current length is greater than the new length, s will be truncated.
var x = @[10, 20] x.setLen(5) x[4] = 50 assert x == @[10, 20, 0, 0, 50] x.setLen(1) assert x == @[10]Source Edit
func setLenUninit[T](s: var seq[T]; newlen: Natural) {.nodestroy.}Sets the length of seq s to newlen. T may be any sequence type. New slots will not be initialized.
If the current length is greater than the new length, s will be truncated.
var x = @[10, 20] x.setLenUninit(5) x[4] = 50 assert x[4] == 50 x.setLenUninit(1) assert x == @[10]Source Edit
proc `shl`(x: int8; y: SomeInteger): int8 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: int16; y: SomeInteger): int16 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: int32; y: SomeInteger): int32 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: int64; y: SomeInteger): int64 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: int; y: SomeInteger): int {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}Computes the shift left operation of x and y.
Note: Operator precedence is different than in C.
Example:
assert 1'i32 shl 4 == 0x0000_0010 assert 1'i64 shl 4 == 0x0000_0000_0000_0010Source Edit
proc `shl`(x: uint8; y: SomeInteger): uint8 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: uint16; y: SomeInteger): uint16 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shl`(x: uint32; y: SomeInteger): uint32 {.magic: "ShlI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: int8; y: SomeInteger): int8 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: int16; y: SomeInteger): int16 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: int32; y: SomeInteger): int32 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: int64; y: SomeInteger): int64 {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: int; y: SomeInteger): int {.magic: "AshrI", noSideEffect,
...raises: [], tags: [], forbids: [].}Computes the shift right operation of x and y, filling vacant bit positions with the sign bit.
Note: Operator precedence is different than in C.
See also:
Example:
assert 0b0001_0000'i8 shr 2 == 0b0000_0100'i8 assert 0b0000_0001'i8 shr 1 == 0b0000_0000'i8 assert 0b1000_0000'i8 shr 4 == 0b1111_1000'i8 assert -1 shr 5 == -1 assert 1 shr 5 == 0 assert 16 shr 2 == 4 assert -16 shr 2 == -4Source Edit
proc `shr`(x: uint8; y: SomeInteger): uint8 {.magic: "ShrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: uint16; y: SomeInteger): uint16 {.magic: "ShrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc `shr`(x: uint32; y: SomeInteger): uint32 {.magic: "ShrI", noSideEffect,
...raises: [], tags: [], forbids: [].}proc sizeof(x: typedesc): int {.magic: "SizeOf", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc sizeof[T](x: T): int {.magic: "SizeOf", noSideEffect, ...raises: [], tags: [],
forbids: [].}Returns the size of x in bytes.
Since this is a low-level proc, its usage is discouraged - using new for the most cases suffices that one never needs to know x's size.
As a special semantic rule, x may also be a type identifier (sizeof(int) is valid).
Limitations: If used for types that are imported from C or C++, sizeof should fallback to the sizeof in the C compiler. The result isn't available for the Nim compiler and therefore can't be used inside of macros.
sizeof('A') # => 1
sizeof(2) # => 8 Source Edit proc slurp(filename: string): string {.magic: "Slurp", ...raises: [], tags: [],
forbids: [].}proc staticExec(command: string; input = ""; cache = ""): string {.
magic: "StaticExec", ...raises: [], tags: [], forbids: [].}Executes an external process at compile-time and returns its text output (stdout + stderr).
If input is not an empty string, it will be passed as a standard input to the executed program.
const buildInfo = "Revision " & staticExec("git rev-parse HEAD") &
"\nCompiled on " & staticExec("uname -v") gorge is an alias for staticExec.
Note that you can use this proc inside a pragma like passc or passl.
If cache is not empty, the results of staticExec are cached within the nimcache directory. Use --forceBuild to get rid of this caching behaviour then. command & input & cache (the concatenated string) is used to determine whether the entry in the cache is still valid. You can use versioning information for cache:
const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0") Source Edit proc staticRead(filename: string): string {.magic: "Slurp", ...raises: [],
tags: [], forbids: [].}Compile-time readFile proc for easy resource embedding:
The maximum file size limit that staticRead and slurp can read is near or equal to the free memory of the device you are using to compile.
const myResource = staticRead"mydatafile.bin"
slurp is an alias for staticRead.
proc substr(s: openArray[char]): string {....raises: [], tags: [], forbids: [].}s into a new string and returns this new string. Example:
let a = "abcdefgh" assert a.substr(2, 5) == "cdef" assert a.substr(2) == "cdefgh" assert a.substr(5, 99) == "fgh"Source Edit
proc substr(s: string; first, last: int): string {....raises: [], tags: [],
forbids: [].}Copies a slice of s into a new string and returns this new string.
The bounds first and last denote the indices of the first and last characters that shall be copied. If last is omitted, it is treated as high(s). If last >= s.len, s.len is used instead: This means substr can also be used to cut or limit a string's length.
Example:
let a = "abcdefgh" assert a.substr(2, 5) == "cdef" assert a.substr(2) == "cdefgh" assert a.substr(5, 99) == "fgh"Source Edit
proc succ[T, V: Ordinal](x: T; y: V = 1): T {.magic: "Succ", noSideEffect,
...raises: [], tags: [], forbids: [].}Returns the y-th successor (default: 1) of the value x.
If such a value does not exist, OverflowDefect is raised or a compile time error occurs.
Example:
assert succ(5) == 6 assert succ(5, 3) == 8Source Edit
proc toFloat(i: int): float {.noSideEffect, inline, ...raises: [], tags: [],
forbids: [].}Converts an integer i into a float. Same as float(i).
If the conversion fails, ValueError is raised. However, on most platforms the conversion cannot fail.
let a = 2 b = 3.7 echo a.toFloat + b # => 5.7Source Edit
proc toInt(f: float): int {.noSideEffect, ...raises: [], tags: [], forbids: [].}Converts a floating point number f into an int.
Conversion rounds f half away from 0, see Round half away from zero, as opposed to a type conversion which rounds towards zero.
Note that some floating point numbers (e.g. infinity or even 1e19) cannot be accurately converted.
doAssert toInt(0.49) == 0 doAssert toInt(0.5) == 1 doAssert toInt(-0.5) == -1 # rounding is symmetricalSource Edit
proc toOpenArray(x: cstring; first, last: int): openArray[char] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc toOpenArray(x: string; first, last: int): openArray[char] {.magic: "Slice",
...raises: [], tags: [], forbids: [].}proc toOpenArray[I, T](x: array[I, T]; first, last: I): openArray[T] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc toOpenArray[T](x: openArray[T]; first, last: int): openArray[T] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc toOpenArray[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc toOpenArray[T](x: seq[T]; first, last: int): openArray[T] {.magic: "Slice",
...raises: [], tags: [], forbids: [].}Allows passing the slice of x from the element at first to the element at last to openArray[T] parameters without copying it.
Example:
proc test(x: openArray[int]) = doAssert x == [1, 2, 3] let s = @[0, 1, 2, 3, 4] s.toOpenArray(1, 3).testSource Edit
proc toOpenArrayByte(x: cstring; first, last: int): openArray[byte] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc toOpenArrayByte(x: openArray[char]; first, last: int): openArray[byte] {.
magic: "Slice", ...raises: [], tags: [], forbids: [].}proc typeof(x: untyped; mode = typeOfIter): typedesc {.magic: "TypeOf",
noSideEffect, compileTime, ...raises: [], tags: [], forbids: [].}typeof operation for accessing the type of an expression. Since version 0.20.0. Example:
proc myFoo(): float = 0.0
iterator myFoo(): string = yield "abc"
iterator myFoo2(): string = yield "abc"
iterator myFoo3(): string {.closure.} = yield "abc"
doAssert type(myFoo()) is string
doAssert typeof(myFoo()) is string
doAssert typeof(myFoo(), typeOfIter) is string
doAssert typeof(myFoo3) is iterator
doAssert typeof(myFoo(), typeOfProc) is float
doAssert typeof(0.0, typeOfProc) is float
doAssert typeof(myFoo3, typeOfProc) is iterator
doAssert not compiles(typeof(myFoo2(), typeOfProc))
# this would give: Error: attempting to call routine: 'myFoo2'
# since `typeOfProc` expects a typed expression and `myFoo2()` can
# only be used in a `for` context. Source Edit proc unsafeNew[T](a: var ref T; size: Natural) {.magic: "New", noSideEffect,
...raises: [], tags: [], forbids: [].}Creates a new object of type T and returns a safe (traced) reference to it in a.
This is unsafe as it allocates an object of the passed size. This should only be used for optimization purposes when you know what you're doing!
See also:
Source Editproc `xor`(x, y: bool): bool {.magic: "Xor", noSideEffect, ...raises: [], tags: [],
forbids: [].}exclusive or; returns true if x != y (if either argument is true while the other is false). Source Edit proc `xor`(x, y: int): int {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise xor of numbers x and y. Example:
assert (0b0011 xor 0b0101) == 0b0110 assert (0b0111 xor 0b1100) == 0b1011Source Edit
proc `xor`(x, y: int8): int8 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `xor`(x, y: int16): int16 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `xor`(x, y: int32): int32 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `xor`(x, y: int64): int64 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `xor`(x, y: uint): uint {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}bitwise xor of numbers x and y. Source Edit proc `xor`(x, y: uint8): uint8 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}proc `xor`(x, y: uint16): uint16 {.magic: "BitxorI", noSideEffect, ...raises: [],
tags: [], forbids: [].}iterator `..`(a, b: int32): int32 {.inline, ...raises: [], tags: [], forbids: [].}A type specialized version of .. for convenience so that mixing integer types works better.
See also:
Source Edititerator `..`(a, b: int64): int64 {.inline, ...raises: [], tags: [], forbids: [].}A type specialized version of .. for convenience so that mixing integer types works better.
See also:
Source Edititerator `..`(a, b: uint32): uint32 {.inline, ...raises: [], tags: [], forbids: [].}A type specialized version of .. for convenience so that mixing integer types works better.
See also:
Source Edititerator `..<`(a, b: int32): int32 {.inline, ...raises: [], tags: [], forbids: [].}..< for convenience so that mixing integer types works better. Source Edit iterator `..<`(a, b: int64): int64 {.inline, ...raises: [], tags: [], forbids: [].}..< for convenience so that mixing integer types works better. Source Edit iterator `..<`(a, b: uint32): uint32 {.inline, ...raises: [], tags: [], forbids: [].}..< for convenience so that mixing integer types works better. Source Edit iterator countdown[T](a, b: T; step: Positive = 1): T {.inline.}Counts from ordinal value a down to b (inclusive) with the given step count.
T may be any ordinal type, step may only be positive.
Note: This fails to count to low(int) if T = int for efficiency reasons.
Example:
import std/sugar
let x = collect(newSeq):
for i in countdown(7, 3):
i
assert x == @[7, 6, 5, 4, 3]
let y = collect(newseq):
for i in countdown(9, 2, 3):
i
assert y == @[9, 6, 3] Source Edit iterator countup[T](a, b: T; step: Positive = 1): T {.inline.}Counts from ordinal value a to b (inclusive) with the given step count.
T may be any ordinal type, step may only be positive.
Note: This fails to count to high(int) if T = int for efficiency reasons.
Example:
import std/sugar
let x = collect(newSeq):
for i in countup(3, 7):
i
assert x == @[3, 4, 5, 6, 7]
let y = collect(newseq):
for i in countup(2, 9, 3):
i
assert y == @[2, 5, 8] Source Edit iterator `||`[S, T](a: S; b: T; annotation: static string = "parallel for"): T {.
inline, magic: "OmpParFor", sideEffect, ...raises: [], tags: [], forbids: [].}OpenMP parallel loop iterator. Same as .. but the loop may run in parallel.
annotation is an additional annotation for the code generator to use. The default annotation is parallel for. Please refer to the OpenMP Syntax Reference for further information.
Note that the compiler maps that to the #pragma omp parallel for construct of OpenMP and as such isn't aware of the parallelism in your code! Be careful! Later versions of || will get proper support by Nim's code generator and GC.
iterator `||`[S, T](a: S; b: T; step: Positive;
annotation: static string = "parallel for"): T {.inline,
magic: "OmpParFor", sideEffect, ...raises: [], tags: [], forbids: [].}OpenMP parallel loop iterator with stepping. Same as countup but the loop may run in parallel.
annotation is an additional annotation for the code generator to use. The default annotation is parallel for. Please refer to the OpenMP Syntax Reference for further information.
Note that the compiler maps that to the #pragma omp parallel for construct of OpenMP and as such isn't aware of the parallelism in your code! Be careful! Later versions of || will get proper support by Nim's code generator and GC.
template alloc(size: Natural): pointer
Allocates a new memory block with at least size bytes.
The block has to be freed with realloc(block, 0) or dealloc(block). The block is not initialized, so reading from it before writing to it is undefined behaviour!
The allocated memory belongs to its allocating thread! Use allocShared to allocate from a shared heap.
See also:
Source Edittemplate alloc0(size: Natural): pointer
Allocates a new memory block with at least size bytes.
The block has to be freed with realloc(block, 0) or dealloc(block). The block is initialized with all bytes containing zero, so it is somewhat safer than alloc.
The allocated memory belongs to its allocating thread! Use allocShared0 to allocate from a shared heap.
Source Edittemplate closureScope(body: untyped): untyped
Useful when creating a closure in a loop to capture local loop variables by their current iteration values.
Note: This template may not work in some cases, use capture instead.
Example:
var myClosure : proc()
# without closureScope:
for i in 0 .. 5:
let j = i
if j == 3:
myClosure = proc() = echo j
myClosure() # outputs 5. `j` is changed after closure creation
# with closureScope:
for i in 0 .. 5:
closureScope: # Everything in this scope is locked after closure creation
let j = i
if j == 3:
myClosure = proc() = echo j
myClosure() # outputs 3 Source Edit template currentSourcePath(): string
Returns the full file-system path of the current source.
To get the directory containing the current source, use it with ospaths2.parentDir() as currentSourcePath.parentDir().
The path returned by this template is set at compile time.
See the docstring of macros.getProjectPath() for an example to see the distinction between the currentSourcePath() and getProjectPath().
See also:
Source Edittemplate likely(val: bool): bool
Hints the optimizer that val is likely going to be true.
You can use this template to decorate a branch condition. On certain platforms this can help the processor predict better which branch is going to be run. Example:
for value in inputValues:
if likely(value <= 100):
process(value)
else:
echo "Value too big!" On backends without branch prediction (JS and the nimscript VM), this template will not affect code execution.
Source Edittemplate realloc(p: pointer; newSize: Natural): pointer
Grows or shrinks a given memory block.
If p is nil then a new memory block is returned. In either way the block has at least newSize bytes. If newSize == 0 and p is not nil realloc calls dealloc(p). In other cases the block has to be freed with dealloc(block).
The allocated memory belongs to its allocating thread! Use reallocShared to reallocate from a shared heap.
Source Edittemplate realloc0(p: pointer; oldSize, newSize: Natural): pointer
Grows or shrinks a given memory block.
If p is nil then a new memory block is returned. In either way the block has at least newSize bytes. If newSize == 0 and p is not nil realloc calls dealloc(p). In other cases the block has to be freed with dealloc(block).
The block is initialized with all bytes containing zero, so it is somewhat safer then realloc
The allocated memory belongs to its allocating thread! Use reallocShared to reallocate from a shared heap.
Source Edittemplate unlikely(val: bool): bool
Hints the optimizer that val is likely going to be false.
You can use this proc to decorate a branch condition. On certain platforms this can help the processor predict better which branch is going to be run. Example:
for value in inputValues:
if unlikely(value > 100):
echo "Value too big!"
else:
process(value) On backends without branch prediction (JS and the nimscript VM), this template will not affect code execution.
Source Edit
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/system.html