Nim is a
general-purpose,
multi-paradigm
Programming languages can be grouped by the number and types of Programming paradigm, paradigms supported.
Paradigm summaries
A concise reference for the programming paradigms listed in this article.
* Concurrent programming language, Concurrent ...
,
statically typed
In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a ''type'' (for example, integer, floating point, string) to every '' term'' (a word, phrase, or other set of symbols). Usu ...
,
compiled high-level system
A system is a group of interacting or interrelated elements that act according to a set of rules to form a unified whole. A system, surrounded and influenced by its open system (systems theory), environment, is described by its boundaries, str ...
programming language
A programming language is a system of notation for writing computer programs.
Programming languages are described in terms of their Syntax (programming languages), syntax (form) and semantics (computer science), semantics (meaning), usually def ...
,
designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant",
supporting
metaprogramming
Metaprogramming is a computer programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modi ...
,
functional,
message passing
In computer science, message passing is a technique for invoking behavior (i.e., running a program) on a computer. The invoking program sends a message to a process (which may be an actor or object) and relies on that process and its supporting ...
,
procedural, and
object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impl ...
styles by providing several features such as
compile time
In computer science, compile time (or compile-time) describes the time window during which a language's statements are converted into binary instructions for the processor to execute. The term is used as an adjective to describe concepts relat ...
code generation,
algebraic data type
In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite data type, i.e., a data type formed by combining other types.
Two common classes of algebraic types are product ty ...
s, a
foreign function interface (FFI) with
C,
C++,
Objective-C
Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing (messaging) to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was ...
, and
JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
, and supporting compiling to those same languages as
intermediate representation
An intermediate representation (IR) is the data structure or code used internally by a compiler or virtual machine to represent source code. An IR is designed to be conducive to further processing, such as optimization and translation. A "good" ...
s.
Description
Nim is statically typed.
It supports compile-time
metaprogramming
Metaprogramming is a computer programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modi ...
features such as syntactic macros and
term rewriting macros.
Term rewriting macros enable
library
A library is a collection of Book, books, and possibly other Document, materials and Media (communication), media, that is accessible for use by its members and members of allied institutions. Libraries provide physical (hard copies) or electron ...
implementations of common data structures, such as bignums and matrices, to be implemented efficiently and with syntactic integration, as if they were built-in language facilities.
Iterators are supported and can be used as first class entities,
as can functions, allowing for the use of
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
methods.
Object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impl ...
is supported by
inheritance
Inheritance is the practice of receiving private property, titles, debts, entitlements, privileges, rights, and obligations upon the death of an individual. The rules of inheritance differ among societies and have changed over time. Offi ...
and
multiple dispatch
Multiple dispatch or multimethods is a feature of some programming languages in which a Subroutine, function or Method (computer programming), method can be dynamic dispatch, dynamically dispatched based on the run time (program lifecycle phase), ...
. Functions can be generic and overloaded, and
generics are further enhanced by Nim's support for
type class
In computer science, a type class is a type system construct that supports ad hoc polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types. Such a constraint typically involves a type class T a ...
es.
Operator overloading is also supported.
Nim includes multiple tunable memory management strategies, including
tracing garbage collection,
reference counting, and
fully manual systems, with the default being deterministic
reference counting with optimizations via
move semantics and
cycle collection via trial deletion.
, Nim compiles to C, C++, JavaScript, Objective-C, and LLVM.
History
Andreas Rumpf is the designer and original implementer of Nim. He received a diploma in computer science from the
University of Kaiserslautern-Landau,
Germany
Germany, officially the Federal Republic of Germany, is a country in Central Europe. It lies between the Baltic Sea and the North Sea to the north and the Alps to the south. Its sixteen States of Germany, constituent states have a total popu ...
. His research interests include hard realtime systems, embedded systems, compiler construction and artificial intelligence.
Nim'soriginal website design by Dominik Picheta and Hugo Locurcio. Joseph Wecker created the Nim logo.
The Nim programming language is a concise, fast programming language that compiles to C, C++ and JavaScript. Nim's initial development was started in 2005 by Andreas Rumpf. It was originally named Nimrod when the project was made public in 2008.
The first version of the Nim
compiler
In computing, a compiler is a computer program that Translator (computing), translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primaril ...
was written in
Pascal using the
Free Pascal compiler.
In 2008, a version of the compiler written in Nim was released.
The compiler is
free and open-source software
Free and open-source software (FOSS) is software available under a license that grants users the right to use, modify, and distribute the software modified or not to everyone free of charge. FOSS is an inclusive umbrella term encompassing free ...
, and is being developed by a community of volunteers working with Andreas Rumpf.
The language was officially renamed from ''Nimrod'' to ''Nim'' with the release of version 0.10.2 in December 2014. On September 23, 2019, version 1.0 of Nim was released, signifying the maturing of the language and its toolchain. On August 1, 2023, version 2.0 of Nim was released, signifying the completion, stabilization of, and switch to the ARC/ORC memory model.
Language design
Syntax
The syntax of Nim resembles that of
Python.
Code blocks and nesting statements are identified through use of
whitespace, according to the
offside-rule. Many
keywords are identical to their Python equivalents, which are mostly English keywords, whereas other programming languages usually use punctuation. With the goal of improving upon its influence languages, even though Nim supports
indentation-based syntax like Python, it introduced additional flexibility. For example, a single
statement may span multiple lines if a comma or
binary operator is at the end of each line. Nim also supports user-defined operators.
Unlike Python, Nim implements (native) static typing. Nim's type system allows for easy
type conversion
In computer science, type conversion, type casting, type coercion, and type juggling are different ways of changing an expression from one data type to another. An example would be the conversion of an integer value into a floating point val ...
, casting, and provides syntax for generic programming. Nim notably provides type classes which can stand in for multiple types, and provides several such type classes 'out of the box'. Type classes allow working with several types as if they were a single type. For example:
*
openarray
Represents arrays of different sizes, sequences, and strings
*
SomeSignedInt
Represents all the signed integer types
*
SomeInteger
Represents all the Integer types, signed or not
*
SomeOrdinal
Represents all the basic countable and ordered types, except of non integer number
This code sample demonstrates the use of typeclasses in Nim:
# Let's declare a function that takes any type of number and displays its double
# In Nim functions with side effect are called "proc"
proc timesTwo(i: SomeNumber) =
echo i * 2
# Let's write another function that takes any ordinal type, and returns
# the double of the input in its original type, if it is a number;
# or returns the input itself otherwise.
# We use a generic Type(T), and precise that it can only be an Ordinal
func twiceIfIsNumber : SomeOrdinali: T): T =
when T is SomeNumber: # A `when` is an `if` evaluated during compile time
result = i * 2 # You can also write `return i * 2`
else:
# If the Ordinal is not a number it is converted to int,
# multiplied by two, and reconverted to its based type
result = (i.int * 2).T
echo twiceIfIsNumber
Influence
According to the language creator, Nim was conceived to combine the best parts of Ada typing system,
Python flexibility, and powerful
Lisp
Lisp (historically LISP, an abbreviation of "list processing") is a family of programming languages with a long history and a distinctive, fully parenthesized Polish notation#Explanation, prefix notation.
Originally specified in the late 1950s, ...
macro system.
Nim was influenced by specific characteristics of existing languages, including the following:
*
Modula-3
Modula-3 is a programming language conceived as a successor to an upgraded version of Modula-2 known as Modula-2+. It has been influential in research circles (influencing the designs of languages such as Java, C#, Python and Nim), but it ha ...
:
traced vs untraced pointers
*
Object Pascal
Object Pascal is an extension to the programming language Pascal (programming language), Pascal that provides object-oriented programming (OOP) features such as Class (computer programming), classes and Method (computer programming), methods.
T ...
: type safe bit sets (''set of char''), case statement syntax, various type names and filenames in the standard library
*
Ada: subrange types, distinct type, safe variants – case objects
*
C++:
operator overloading,
generic programming
*
Python:
Off-side rule
*
Lisp
Lisp (historically LISP, an abbreviation of "list processing") is a family of programming languages with a long history and a distinctive, fully parenthesized Polish notation#Explanation, prefix notation.
Originally specified in the late 1950s, ...
:
Macro system,
AST manipulation,
homoiconicity
In computer programming, homoiconicity (from the Greek words ''homo-'' meaning "the same" and ''icon'' meaning "representation") is an informal property of some programming languages. A language is homoiconic if a program written in it can be mani ...
*
Oberon
Oberon () is a king of the fairy, fairies in Middle Ages, medieval and Renaissance literature. He is best known as a character in William Shakespeare's play ''A Midsummer Night's Dream'', in which he is King of the Fairies and spouse of Titania ...
: export marker
*
C#:
async/await, lambda macros
*
ParaSail: pointer-free programming
Uniform function call syntax
Nim supports
uniform function call syntax (UFCS) and identifier equality, which provides a large degree of flexibility in use.
For example, each of these lines print
"hello world", just with different syntax:
echo "hello world"
echo("hello world")
"hello world".echo()
"hello world".echo
echo("hello", " world")
"hello".echo(" world")
"hello".echo " world"
Identifier equality
Nim is almost fully style-insensitive; two
identifier
An identifier is a name that identifies (that is, labels the identity of) either a unique object or a unique ''class'' of objects, where the "object" or class may be an idea, person, physical countable object (or class thereof), or physical mass ...
s are considered equal if they only differ by capitalization and underscores, as long as the first characters are identical. This is to enable a mixture of styles across libraries: one user can write a library using snake_case as a convention, and it can be used by a different user in a camelCase style without issue.
const useHttps = true
assert useHttps useHttps
assert useHTTPS useHttps
assert use_https useHttps
Stropping
The
stropping feature allows the use of any name for variables or functions, even when the names are
reserved word
In a programming language, a reserved word (sometimes known as a reserved identifier) is a word that cannot be used by a programmer as an identifier, such as the name of a variable, function, or label – it is "reserved from use". In brief, an '' ...
s for keywords. An example of stropping is the ability to define a variable named
if
, without clashing with the keyword
if
. Nim's implementation of this is achieved via backticks, allowing any reserved word to be used as an identifier.
type Type = object
`int`: int
let `object` = Type(`int`: 9)
assert `object` is Type
assert `object`.`int` 9
var `var` = 42
let `let` = 8
assert `var` + `let` 50
const `assert` = true
assert `assert`
Compiler
The Nim compiler emits fast, optimized
C code by default. It defers compiling-to-object code to an external C compiler
to leverage existing compiler optimization and portability. Many C compilers are supported, including
Clang
Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler ...
,
Microsoft Visual C++ (MSVC),
MinGW, and
GNU Compiler Collection
The GNU Compiler Collection (GCC) is a collection of compilers from the GNU Project that support various programming languages, Computer architecture, hardware architectures, and operating systems. The Free Software Foundation (FSF) distributes ...
(GCC). The Nim compiler can also emit
C++,
Objective-C
Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing (messaging) to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was ...
, and
JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
code to allow easy interfacing with application programming interfaces (
API
An application programming interface (API) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how to build ...
s) written in those languages;
developers can simply write in Nim, then compile to any supported language. This also allows writing applications for
iOS and
Android. There is also an unofficial
LLVM
LLVM, also called LLVM Core, is a target-independent optimizer and code generator. It can be used to develop a Compiler#Front end, frontend for any programming language and a Compiler#Back end, backend for any instruction set architecture. LLVM i ...
backend, allowing use of the Nim compiler in a stand-alone way.
The Nim compiler is
self-hosting, meaning it is written in the Nim language. The compiler supports cross-compiling, so it is able to compile software for any of the supported operating systems, no matter the development machine. This is useful for compiling applications for embedded systems, and for uncommon and obscure computer architectures.
Compiler options
By default, the Nim compiler creates a ''debug'' build.
With the option
-d:release
a ''release'' build can be created, which is optimized for speed and contains fewer runtime checks.
With the option
-d:danger
all runtime checks can be disabled, if maximum speed is desired.
Memory management
Nim supports multiple memory management strategies, including the following:
*
--mm:arc
– Automatic
reference counting (ARC) with
move semantics optimizations, offers a shared heap. It offers fully deterministic performance for hard realtime systems. Reference cycles may cause memory leaks: these may be dealt with by manually annotating
pragmas or by using
--mm:orc
.
*
--mm:orc
– Same as
--mm:arc
but adds a cycle collector (the "O") based on "trial deletion". The cycle collector only analyzes types if they are potentially cyclic.
*
--mm:refc
– Standard deferred
reference counting based
garbage collector with a simple mark-and-sweep backup GC in order to collect cycles. Heaps are thread-local.
*
--mm:markAndSweep
– Simple
mark-and-sweep based
garbage collector. Heaps are thread-local.
*
--mm:boehm
–
Boehm based
garbage collector, it offers a shared heap.
*
--mm:go
–
Go's
garbage collector, useful for interoperability with
Go. Offers a shared heap.
*
--mm:none
– No memory management strategy nor a
garbage collector. Allocated memory is simply never freed, unless manually freed by the developer's code.
As of Nim 2.0, ORC is the default GC.
Development tools
Bundled
Many tools are bundled with the Nim install package, including:
Nimble
Nimble is the standard
package manager
A package manager or package management system is a collection of software tools that automates the process of installing, upgrading, configuring, and removing computer programs for a computer in a consistent manner.
A package manager deals wi ...
used by Nim to package Nim modules. It was initially developed by Dominik Picheta, who is also a core Nim developer. Nimble has been included as Nim's official package manager since Oct 27, 2015, the v0.12.0 release.
Nimble packages are defined by
.nimble
files, which contain information about the package version, author, license, description, dependencies, and more.
These files support a limited subset of the Nim syntax called NimScript, with the main limitation being the access to the FFI. These scripts allow changing of test procedure, or for custom tasks to be written.
The list of packages is stored in a JavaScript Object Notation (
JSON
JSON (JavaScript Object Notation, pronounced or ) is an open standard file format and electronic data interchange, data interchange format that uses Human-readable medium and data, human-readable text to store and transmit data objects consi ...
) file which is freely accessible in the nim-lang/packages repository on GitHub. This JSON file provides Nimble with a mapping between the names of packages and their Git or Mercurial repository URLs.
Nimble comes with the Nim compiler. Thus, it is possible to test the Nimble environment by running:
nimble -v
.
This command will reveal the version number, compiling date and time, and
Git hash of nimble. Nimble uses the Git package, which must be available for Nimble to function properly. The Nimble command-line is used as an interface for installing, removing (uninstalling), and upgrading–patching module packages.
c2nim
c2nim is a
source-to-source compiler
A source-to-source translator, source-to-source compiler (S2S compiler), transcompiler, or transpiler is a type of translator that takes the source code of a program written in a programming language as its input and produces an equivalent so ...
(transcompiler or transpiler) meant to be used on
C/
C++ headers to help generate new Nim bindings. The output is human-readable Nim code that is meant to be edited by hand after the translation process.
koch
koch is a maintenance script that is used to build Nim, and provide HTML documentation.
nimgrep
nimgrep is a generic tool for manipulating text. It is used to search for regex, peg patterns, and contents of directories, and it can be used to replace tasks. It is included to assist with searching Nim's style-insensitive identifiers.
nimsuggest
nimsuggest is a tool that helps any source code editor query a
.nim
source file to obtain useful information like definition of symbols or suggestions for completions.
niminst
niminst is a tool to generate an installer for a Nim program.
It creates .msi installers for Windows via Inno Setup, and install and uninstall scripts for
Linux
Linux ( ) is a family of open source Unix-like operating systems based on the Linux kernel, an kernel (operating system), operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically package manager, pac ...
,
macOS
macOS, previously OS X and originally Mac OS X, is a Unix, Unix-based operating system developed and marketed by Apple Inc., Apple since 2001. It is the current operating system for Apple's Mac (computer), Mac computers. With ...
, and
Berkeley Software Distribution
The Berkeley Software Distribution (BSD), also known as Berkeley Unix or BSD Unix, is a discontinued Unix operating system developed and distributed by the Computer Systems Research Group (CSRG) at the University of California, Berkeley, beginn ...
(BSD).
nimpretty
nimpretty is a source code beautifier, used to format code according to the official Nim style guide.
Testament
Testamentis an advanced automatic unit tests runner for Nim tests. Used in developing Nim, it offers process isolation tests, generates statistics about test cases, supports multiple targets and simulated Dry-Runs, has logging, can generate HTML reports, can skip tests from a file, and more.
Other notable tools
Some notable tools not included in the Nim distribution include:
choosenim
choosenimwas developed by Dominik Picheta, creator of the Nimble package manager, as a tool to enable installing and using multiple versions of the Nim compiler. It downloads any Nim stable or development compiler version from the command line, enabling easy switching between them.
nimpy
nimpyis a library that enables convenient Python integration in Nim programs.
pixie
pixieis a feature-rich 2D graphics library, similar to
Cairo
Cairo ( ; , ) is the Capital city, capital and largest city of Egypt and the Cairo Governorate, being home to more than 10 million people. It is also part of the List of urban agglomerations in Africa, largest urban agglomeration in Africa, L ...
or the
Skia. It uses
SIMD
Single instruction, multiple data (SIMD) is a type of parallel computer, parallel processing in Flynn's taxonomy. SIMD describes computers with multiple processing elements that perform the same operation on multiple data points simultaneousl ...
acceleration to speed-up image manipulation drastically. It supports many image formats, blending, masking, blurring, and can be combined with th
boxylibrary to do hardware accelerated rendering.
nimterop
nimteropis a tool focused on automating the creation of C/C++ wrappers needed for Nim's foreign function interface.
Libraries
Pure/impure libraries
Pure libraries are modules written in Nim only. They include no wrappers to access libraries written in other programming languages.
Impure libraries are modules of Nim code which depend on external libraries that are written in other programming languages such as C.
Standard library
The Nim standard library includes modules for all basic tasks, including:
* System and core modules
* Collections and algorithms
* String handling
* Time handling
* Generic Operating System Services
* Math libraries
* Internet Protocols and Support
* Threading
* Parsers
* Docutils
* XML Processing
* XML and HTML code generator
* Hashing
* Database support (PostgreSQL, MySQL and SQLite)
* Wrappers (Win32 API, POSIX)
Use of other libraries
A Nim program can use any
library
A library is a collection of Book, books, and possibly other Document, materials and Media (communication), media, that is accessible for use by its members and members of allied institutions. Libraries provide physical (hard copies) or electron ...
which can be used in a C, C++, or JavaScript program.
Language bindings exist for many libraries, including
GTK
GTK (formerly GIMP ToolKit and GTK+) is a free software cross-platform widget toolkit for creating graphical user interfaces (GUIs). It is licensed under the terms of the GNU Lesser General Public License, allowing both Free software, free and ...
,
Qt QML,
wxWidgets
wxWidgets (formerly wxWindows) is a widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications. wxWidgets enables a program's GUI code to compile and run on several computer platforms with no s ...
,
SDL 2,
Raylib,
Godot,
UE5,
Cairo
Cairo ( ; , ) is the Capital city, capital and largest city of Egypt and the Cairo Governorate, being home to more than 10 million people. It is also part of the List of urban agglomerations in Africa, largest urban agglomeration in Africa, L ...
,
OpenGL
OpenGL (Open Graphics Library) is a Language-independent specification, cross-language, cross-platform application programming interface (API) for rendering 2D computer graphics, 2D and 3D computer graphics, 3D vector graphics. The API is typic ...
,
Vulkan,
WinAPI,
zlib
zlib ( or "zeta-lib", ) is a software library used for data compression as well as a data format. zlib was written by Jean-loup Gailly and Mark Adler and is an abstraction of the DEFLATE compression algorithm used in their gzip file compre ...
,
libzip,
OpenSSL and
cURL.
Nim works with
PostgreSQL,
MySQL
MySQL () is an Open-source software, open-source relational database management system (RDBMS). Its name is a combination of "My", the name of co-founder Michael Widenius's daughter My, and "SQL", the acronym for Structured Query Language. A rel ...
, and
SQLite databases.
There are open source tools of various degree of support that can be used to interface Nim with
Lua,
Julia,
Rust
Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
,
C#,
and
Python programming languages or transpile Nim to
TypeScript
TypeScript (abbreviated as TS) is a high-level programming language that adds static typing with optional type annotations to JavaScript. It is designed for developing large applications and transpiles to JavaScript. It is developed by Micr ...
.
Examples
Hello world
The
"Hello, World!" program
A "Hello, World!" program is usually a simple computer program that emits (or displays) to the screen (often the Console application, console) a message similar to "Hello, World!". A small piece of code in most general-purpose programming languag ...
in Nim:
echo("Hello, World!")
# Procedures can be called with no parentheses
echo "Hello, World!"
Another version of "Hello World" can be accomplished by calling the
write
function with the
stdout
stream:
stdout.write("Hello, World!\n")
write(stdout, "Hello, World!\n")
Fibonacci
Several implementations of the
Fibonacci function, showcasing implicit returns, default parameters, iterators, recursion, and while loops:
proc fib(n: Natural): Natural =
if n < 2:
return n
else:
return fib(n-1) + fib(n-2)
func fib2(n: int, a = 0, b = 1): int =
if n 0: a else: fib2(n-1, b, a+b)
iterator fib3: int =
var a = 0
var b = 1
while true:
yield a
swap a, b
b += a
Factorial
Program to calculate the
factorial
In mathematics, the factorial of a non-negative denoted is the Product (mathematics), product of all positive integers less than or equal The factorial also equals the product of n with the next smaller factorial:
\begin
n! &= n \times ...
of a positive integer using the iterative approach, showcasing try/catch error handling and for loops:
import std/strutils
var n = 0
try:
stdout.write "Input positive integer number: "
n = stdin.readline.parseInt
except ValueError:
raise newException(ValueError, "You must enter a positive number")
var fact = 1
for i in 2..n:
fact = fact * i
echo fact
Using the module math from Nim's standard library:
import std/math
echo fac(x)
Reversing a string
A simple demonstration showing the implicit result variable and the use of iterators.
proc reverse(s: string): string =
for i in countdown(s.high, 0):
result.add s
let str1 = "Reverse This!"
echo "Reversed: ", reverse(str1)
One of Nim's more exotic features is the implicit
result
variable. Every procedure in Nim with a non-void return type has an implicit result variable that represents the value to be returned. In the for loop we see an invocation of
countdown
which is an iterator. If an iterator is omitted, the compiler will attempt to use an
items
iterator, if one is defined for the type specified.
Graphical user interface
Using
GTK 3 with GObject introspection through th
gintromodule:
import gintro/ tk, glib, gobject, gio
proc appActivate(app: Application) =
let window = newApplicationWindow(app)
window.title = "GTK3 application with gobject introspection"
window.defaultSize = (400, 400)
showAll(window)
proc main =
let app = newApplication("org.gtk.example")
connect(app, "activate", appActivate)
discard run(app)
main()
This code requires the gintro module to work, which is not part of the standard library. To install the module gintro and many others you can use the tool nimble, which comes as part of Nim. To install the gintro module with nimble you do the following:
nimble install gintro
Programming paradigms
Functional programming
Functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
is supported in Nim through
first-class function
In computer science, a programming language is said to have first-class functions if it treats function (programming), functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning ...
s and code without
side effects
In medicine, a side effect is an effect of the use of a medicinal drug or other treatment, usually adverse but sometimes beneficial, that is unintended. Herbal and traditional medicines also have side effects.
A drug or procedure usually used ...
via the
noSideEffect
pragma or the
func
keyword. Nim will perform
side effect
In medicine, a side effect is an effect of the use of a medicinal drug or other treatment, usually adverse but sometimes beneficial, that is unintended. Herbal and traditional medicines also have side effects.
A drug or procedure usually use ...
analysis and raise compiling errors for code that does not obey the contract of producing no
side effects
In medicine, a side effect is an effect of the use of a medicinal drug or other treatment, usually adverse but sometimes beneficial, that is unintended. Herbal and traditional medicines also have side effects.
A drug or procedure usually used ...
when compiled with the experimental feature
strictFuncs
, planned to become the default in later versions.
Contrary to purely
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
languages, Nim is a
multi-paradigm
Programming languages can be grouped by the number and types of Programming paradigm, paradigms supported.
Paradigm summaries
A concise reference for the programming paradigms listed in this article.
* Concurrent programming language, Concurrent ...
programming language, so
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
restrictions are opt-in on a function-by-function basis.
First-class functions
Nim supports
first-class function
In computer science, a programming language is said to have first-class functions if it treats function (programming), functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning ...
s by allowing functions to be stored in variables or passed anonymously as parameters to be invoked by other functions. The
std/sugar
module provides syntactic sugar for anonymous functions in type declarations and instantiation.
import std/ equtils, sugar
let powersOfTwo = @ , 2, 4, 8, 16, 32, 64, 128, 256
proc filter s: openArray pred: T -> bool): seq =
result = newSeq )
for i in 0 ..< s.len:
if pred(s :
result.add(s
echo powersOfTwo.filter(proc (x: int): bool = x > 32)
# syntactic sugar for the above, provided as a macro from std/sugar
echo powersOfTwo.filter(x => x > 32)
proc greaterThan32(x: int): bool = x > 32
echo powersOfTwo.filter(greaterThan32)
Side effects
Side effects of functions annotated with the
noSideEffect
pragma are checked, and the compiler will refuse to compile functions failing to meet those. Side effects in Nim include mutation, global state access or modification, asynchronous code, threaded code, and IO. Mutation of parameters may occur for functions taking parameters of
var
or
ref
type: this is expected to fail to compile with the currently-experimental
strictFuncs
in the future. The
func
keyword introduces a shortcut for a
noSideEffect
pragma.
Function composition
Uniform function call syntax allows the
chaining of arbitrary functions, perhaps best exemplified with the
std/sequtils
library.
import std/ equtils, sugar
let numbers = @ , 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1# a and b are special identifiers in the foldr macro
echo numbers.filter(x => x > 3).deduplicate.foldr(a + b) # 30
Algebraic data types and pattern matching
Nim has support for
product types via the
object
type, and for
sum types via
object variants: raw representations of
tagged union
In computer science, a tagged union, also called a variant, variant record, choice type, discriminated union, disjoint union, sum type, or coproduct, is a data structure used to hold a value that could take on several different, but fixed, types. ...
s, with an enumerated type tag that must be
safely matched upon before fields of variants can be accessed. These types can be
composed algebraically.
Structural pattern matching is available, but relegated to macros in various third-party libraries.
import std/tables
type
Value = uint64
Ident = string
ExprKind = enum
Literal, Variable, Abstraction, Application
Expr = ref object
case kind: ExprKind
of Literal:
litIdent: Value
of Variable:
varIdent: Ident
of Abstraction:
paramAbs: Ident
funcAbs: Expr
of Application:
funcApp, argApp: Expr
func eval(expr: Expr, context: var Table dent, Value: Value =
case expr.kind
of Literal:
return expr.litIdent
of Variable:
return context xpr.varIdent of Application:
case expr.funcApp.kind
of Abstraction:
context xpr.funcApp.paramAbs= expr.argApp.eval(context)
return expr.funcAbs.eval(context)
else:
raise newException(ValueError, "Invalid expression!")
else:
raise newException(ValueError, "Invalid expression!")
Object-oriented programming
Despite being primarily an imperative and functional language, Nim supports various features for enabling object-oriented paradigms.
Subtyping and inheritance
Nim supports limited inheritance by use of
ref objects
and the
of
keyword.
To enable inheritance, any initial ("root") object must inherit from
RootObj
. Inheritance is of limited use within idiomatic Nim code: with the notable exception of Exceptions.
type Animal = ref object of RootObj
name: string
age: int
type Dog = ref object of Animal
type Cat = ref object of Animal
var animals: seq nimal= @[]
animals.add(Dog(name: "Sparky", age: 10))
animals.add(Cat(name: "Mitten", age: 10))
for a in animals:
assert a of Animal
Subtyping relations can also be queried with the
of
keyword.
Method calls and encapsulation
Nim's
uniform function call syntax enables calling ordinary functions with syntax similar to method call invocations in other programming languages. This is functional for "getters": and Nim also provides syntax for the creation of such "setters" as well. Objects may be made public on a per-field basis, providing for encapsulation.
type Socket* = ref object
host: int # private, lacks export marker
# getter of host address
proc host*(s: Socket): int = s.host
# setter of host address
proc `host=`*(s: var Socket, value: int) =
s.host = value
var s: Socket
new s
assert s.host 0 # same as host(s), s.host()
s.host = 34 # same as `host=`(s, 34)
Dynamic dispatch
Static dispatch is preferred, more performant, and standard even among method-looking routines.
Nonetheless, if dynamic dispatch is so desired, Nim provides the
method
keyword for enabling
dynamic dispatch on reference types.
import std/strformat
type
Person = ref object of RootObj
name: string
Student = ref object of Person
Teacher = ref object of Person
method introduce(a: Person) =
raise newException(CatchableError, "Method without implementation override")
method introduce(a: Student) =
echo &"I am a student named !"
method introduce(a: Teacher) =
echo &"I am a teacher named !"
let people: seq erson= @ eacher(name: "Alice"), Student(name: "Bob")for person in people:
person.introduce()
Metaprogramming
Templates
Nim supports simple substitution on the abstract syntax tree via its templates.
template genType(name, fieldname: untyped, fieldtype: typedesc) =
type
name = object
fieldname: fieldtype
genType(Test, foo, int)
var x = Test(foo: 4566)
echo(x.foo) # 4566
The
genType
is invoked at compile-time and a
Test
type is created.
Generics
Nim supports both constrained and unconstrained generic programming.
Generics may be used in procedures, templates and macros. Unconstrained generic identifiers (
T
in this example) are defined after the routine's name in square brackets. Constrained generics can be placed on generic identifiers, or directly on parameters.
proc addThese a, b: T): T = a + b
echo addThese(1, 2) # 3 (of int type)
echo addThese(uint8 1, uint8 2) # 3 (of uint8 type)
# we don't want to risk subtracting unsigned numbers!
proc subtractThese floata, b: T): T = a - b
echo subtractThese(1, 2) # -1 (of int type)
import std/sequtils
# constrained generics can also be directly on the parameters
proc compareThese a, b: string , seq : bool =
for (i, j) in zip(a, b):
if i != j:
return false
One can further clarify which types the procedure will accept by specifying a type class (in the example above,
SomeSignedInt
).
Macros
Macros can rewrite parts of the code at compile-time. Nim macros are powerful and can operate on the abstract syntax tree before or after semantic checking.
Here's a simple example that creates a macro to call code twice:
import std/macros
macro twice(arg: untyped): untyped =
result = quote do:
`arg`
`arg`
twice echo "Hello world!"
The
twice
macro in this example takes the echo statement in the form of an abstract syntax tree as input. In this example we decided to return this syntax tree without any manipulations applied to it. But we do it twice, hence the name of the macro. The result is that the code gets rewritten by the macro to look like the following code at compile time:
echo "Hello world!"
echo "Hello world!"
Foreign function interface (FFI)
Nim's FFI is used to call functions written in the other programming languages that it can compile to. This means that libraries written in C, C++, Objective-C, and JavaScript can be used in the Nim source code. One should be aware that both JavaScript and C, C++, or Objective-C libraries cannot be combined in the same program, as they are not as compatible with JavaScript as they are with each other. Both C++ and Objective-C are based on and compatible with C, but JavaScript is incompatible, as a dynamic, client-side web-based language.
The following program shows the ease with which external C code can be used directly in Nim.
proc printf(formatstr: cstring)
printf("%s %d\n", "foo", 5)
In this code the
printf
function is imported into Nim and then used.
Basic example using 'console.log' directly for the
JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
compiling target:
proc log(args: any)
log(42, "z", true, 3.14)
The JavaScript code produced by the Nim compiler can be executed with
Node.js or a web browser.
Parallelism
To activate threading support in Nim, a program should be compiled with
--threads:on
command line argument. Each thread has a separate garbage collected heap and sharing of memory is restricted, which helps with efficiency and stops race conditions by the threads.
import std/locks
var
thr: array ..4, Thread[tuple[a,b: int">uple[a,b: int">..4, Thread[tuple[a,b: int L: Lock
proc threadFunc(interval: tuple[a,b: int">,b: int">..4, Thread[tuple[a,b: int">uple[a,b: int">..4, Thread[tuple[a,b: int L: Lock
proc threadFunc(interval: tuple[a,b: int =
for i in interval.a..interval.b:
acquire(L) # lock stdout
echo i
release(L)
initLock(L)
for i in 0..high(thr):
createThread(thr[i], threadFunc, (i*10, i*10+5))
joinThreads(thr)
Nim also has a
channels
module that simplifies passing data between threads.
import std/os
type
CalculationTask = object
id*: int
data*: int
CalculationResult = object
id*: int
result*: int
var task_queue: Channel alculationTaskvar result_queue: Channel alculationResult
proc workerFunc() =
result_queue.open()
while true:
var task = task_queue.recv()
result_queue.send(CalculationResult(id: task.id, result: task.data * 2))
var workerThread: Thread oidcreateThread(workerThread, workerFunc)
task_queue.open()
task_queue.send(CalculationTask(id: 1, data: 13))
task_queue.send(CalculationTask(id: 2, data: 37))
while true:
echo "got result: ", repr(result_queue.recv())
Concurrency
Asynchronous IO is supported either via the
asyncdispatch
module in the standard library or the external
chronos
library. Both libraries add
async/await syntax via the macro system, without need for special language support. An example of an asynchronous
HTTP
HTTP (Hypertext Transfer Protocol) is an application layer protocol in the Internet protocol suite model for distributed, collaborative, hypermedia information systems. HTTP is the foundation of data communication for the World Wide Web, wher ...
server:
import std/ synchttpserver, asyncdispatch# chronos could also be alternatively used in place of asyncdispatch,
# with no other changes.
var server = newAsyncHttpServer()
proc cb(req: Request) =
await req.respond(Http200, "Hello World")
waitFor server.serve(Port(8080), cb)
Community
Online
Nim has an active community on the self-hosted, self-developed official forum. Further, the project uses a Git repository, bug tracker, RFC tracker, and wiki hosted by
GitHub
GitHub () is a Proprietary software, proprietary developer platform that allows developers to create, store, manage, and share their code. It uses Git to provide distributed version control and GitHub itself provides access control, bug trackin ...
, where the community engages with the language. There are also official online chat rooms, bridged between
IRC
IRC (Internet Relay Chat) is a text-based chat system for instant messaging. IRC is designed for group communication in discussion forums, called '' channels'', but also allows one-on-one communication via private messages as well as chat ...
,
Matrix
Matrix (: matrices or matrixes) or MATRIX may refer to:
Science and mathematics
* Matrix (mathematics), a rectangular array of numbers, symbols or expressions
* Matrix (logic), part of a formula in prenex normal form
* Matrix (biology), the m ...
,
Discord,
Gitter, and
Telegram
Telegraphy is the long-distance transmission of messages where the sender uses symbolic codes, known to the recipient, rather than a physical exchange of an object bearing the message. Thus flag semaphore is a method of telegraphy, whereas pi ...
.
Conventions
The first Nim conference, NimConf, took place on June 20, 2020. It was held digitally due to
COVID-19
Coronavirus disease 2019 (COVID-19) is a contagious disease caused by the coronavirus SARS-CoV-2. In January 2020, the disease spread worldwide, resulting in the COVID-19 pandemic.
The symptoms of COVID‑19 can vary but often include fever ...
, with an open call for contributor talks in the form of
YouTube
YouTube is an American social media and online video sharing platform owned by Google. YouTube was founded on February 14, 2005, by Steve Chen, Chad Hurley, and Jawed Karim who were three former employees of PayPal. Headquartered in ...
videos. The conference began with language overviews by Nim developers Andreas Rumpf and Dominik Picheta. Presentation topics included talks about web frameworks,
mobile development,
Internet of things
Internet of things (IoT) describes devices with sensors, processing ability, software and other technologies that connect and exchange data with other devices and systems over the Internet or other communication networks. The IoT encompasse ...
(IoT) devices, and
game development, including a talk about writing Nim for
Game Boy Advance
The (GBA) is a 32-bit handheld game console, manufactured by Nintendo, which was released in Japan on March 21, 2001, and to international markets that June. It was later released in mainland China in 2004, under the name iQue Game Boy Advanc ...
. NimConf 2020 is available as a YouTube playlist. NimConf 2021 occurred the following year, was also held digitally, and included talks about
game development,
REPLs,
real-time operating system
A real-time operating system (RTOS) is an operating system (OS) for real-time computing applications that processes data and events that have critically defined time constraints. A RTOS is distinct from a time-sharing operating system, such as Unix ...
s, Nim in the industry,
object-relational mapping (ORM),
fuzzing
In programming and software development, fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. The program is then monitored for exceptio ...
,
language design, and
graphics libraries.
In addition to official conferences, Nim has been featured at various other conventions. A presentation on Nim was given at the
O'Reilly Open Source Convention (OSCON) in 2015. Four speakers represented Nim at
FOSDEM
Free and Open source Software Developers' European Meeting (FOSDEM) is an annual software engineering conference. It is non-commercial and volunteer-organized with a focus on free and open-source software. Initiated in 2000, it is usually held d ...
2020, including the creator of the language, Andreas Rumpf. At FOSDEM 2022, Nim hosted their own developer room virtually due to the
COVID-19 pandemic
The COVID-19 pandemic (also known as the coronavirus pandemic and COVID pandemic), caused by severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2), began with an disease outbreak, outbreak of COVID-19 in Wuhan, China, in December ...
. Talks were held on
concurrency,
embedded programming, programming for
GPUs,
entity-component systems,
game development,
rules engines,
Python interop
Interop is an annual information technology conference organised by Informa PLC. Founded in 1986, the event takes place in the US and Tokyo (Japan) each year. Interop promotes interoperability and openness, beginning with IP networks and continu ...
, and
metaprogramming
Metaprogramming is a computer programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modi ...
.
See also
*
Crystal (programming language)
*
D (programming language)
D, also known as dlang, is a multi-paradigm system programming language created by Walter Bright at Digital Mars and released in 2001. Andrei Alexandrescu joined the design and development effort in 2007. Though it originated as a re-engin ...
*
Fat pointer
References
External links
*
*
Information about Nimon
Stack Overflow
In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. The size of the call stack depends on many fa ...
Computer Programming with the Nim Programming Language A gentle Introduction by Stefan Salewski
{{JavaScript
2008 software
Concurrent programming languages
Cross-platform software
Functional languages
Multi-paradigm programming languages
Procedural programming languages
Programming languages
Programming languages created in 2008
Software using the MIT license
Source-to-source compilers
Statically typed programming languages
Systems programming languages