Nim is a
general-purpose,
multi-paradigm
Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms.
Some paradigms are concerned mainly with implications for the execution model of the language, suc ...
,
statically typed,
compiled
In computing, a compiler is a computer program that translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primarily used for programs tha ...
systems programming language,
designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant",
supporting
metaprogramming,
functional
Functional may refer to:
* Movements in architecture:
** Functionalism (architecture)
** Form follows function
* Functional group, combination of atoms within molecules
* Medical conditions without currently visible organic basis:
** Functional sy ...
,
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", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
styles by providing several features such as
compile time
In computer science, compile time (or compile-time) describes the time window during which a computer program is compiled.
The term is used as an adjective to describe concepts related to the context of program compilation, as opposed to concep ...
code generation,
algebraic data type
In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite type, i.e., a type formed by combining other types.
Two common classes of algebraic types are product types (i.e., ...
s, a
foreign function interface (FFI) with
C,
C++,
Objective-C
Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXT ...
, and
JavaScript
JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of websites use JavaScript on the client side for webpage behavior, of ...
, 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 was created to be a language as fast as C, as expressive as
Python, and as extensible as
Lisp
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lispin ...
.
Nim is statically typed.
It supports compile-time
metaprogramming features such as syntactic macros and
term rewriting macros.
Term rewriting macros enable
library
A library is a collection of materials, books or media that are accessible for use and not just for display purposes. A library provides physical (hard copies) or digital access (soft copies) materials, and may be a physical location or a vi ...
implementations of common data structures, such as bignums and matrices, to be implemented efficiently, 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 applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
methods. Object-oriented programming 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. Of ...
and
multiple dispatch. Functions can be generic, they can be overloaded, and
generics
Generic or generics may refer to:
In business
* Generic term, a common name used for a range or class of similar things not protected by trademark
* Generic brand, a brand for a product that does not have an associated brand or trademark, other ...
are further enhanced by Nim's support for type classes.
Operator overloading is also supported.
Nim includes tunable automatic
garbage collection
Waste collection is a part of the process of waste management. It is the transfer of solid waste from the point of use and disposal to the point of treatment or landfill. Waste collection also includes the curbside collection of recyclabl ...
based on deferred
reference counting
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, refer ...
with
cycle detection
In computer science, cycle detection or cycle finding is the algorithmic problem of finding a cycle in a sequence of iterated function values.
For any function that maps a finite set to itself, and any initial value in , the sequence of iter ...
, which can also be turned off altogether.
, Nim compiles to C, C++, JavaScript, and Objective-C.
History
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 translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primarily used for programs tha ...
was written in
Pascal
Pascal, Pascal's or PASCAL may refer to:
People and fictional characters
* Pascal (given name), including a list of people with the name
* Pascal (surname), including a list of people and fictional characters with the name
** Blaise Pascal, Frenc ...
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 a term used to refer to groups of software consisting of both free software and open-source software where anyone is freely licensed to use, copy, study, and change the software in any way, and the source ...
, 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.0 of Nim was released, signifying the maturing of the language and its toolchain.
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
In mathematics, a binary operation or dyadic operation is a rule for combining two elements (called operands) to produce another element. More formally, a binary operation is an operation of arity two.
More specifically, an internal binary o ...
is at the end of each line. And Nim supports user-defined operators.
Unlike Python, Nim implements (native) static typing. Nim's type system allows for easy
type conversion, 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:
*
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 twice_if_is_number : 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 twice_if_is_number(67) # Passes an int to the function
echo twice_if_is_number(67u8) # Passes an uint8
echo twice_if_is_number(true) # Passes a bool (Which is also an Ordinal)
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, physical countable object (or class thereof), or physical noncountable ...
s are considered equal if they only differ by capitalization and underscores, as long as the first characters are identical. Historically, Nim was fully
case-insensitive (capitalization of the identifiers was fully ignored) and underscores were completely ignored, too.
Influence
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+. While it has been influential in research circles (influencing the designs of languages such as Java, C#, and Python) it has not ...
:
traced vs untraced pointers
*
Object Pascal
Object Pascal is an extension to the programming language Pascal that provides object-oriented programming (OOP) features such as classes and methods.
The language was originally developed by Apple Computer as ''Clascal'' for the Lisa Worksh ...
: type safe bit sets (''set of char''), case statement syntax, various type names and filenames in the standard library
*
Ada
Ada may refer to:
Places
Africa
* Ada Foah, a town in Ghana
* Ada (Ghana parliament constituency)
* Ada, Osun, a town in Nigeria
Asia
* Ada, Urmia, a village in West Azerbaijan Province, Iran
* Ada, Karaman, a village in Karaman Province, T ...
: subrange types, distinct type, safe variants – case objects
*
C++:
operator overloading,
generic programming
*
Python:
Off-side rule
*
Lisp
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lispin ...
: Macro system, embrace the
AST,
homoiconicity
*
Oberon
Oberon () is a king of the fairies in 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, Queen of the Fairi ...
: export marker
*
C#: async –
await
In computer programming, the async/await pattern is a syntactic feature of many programming languages that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function. It is semantically rel ...
, lambda macros
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"
echo("hello world")
"hello world".echo()
"hello world".echo
# echo("hello", " world")
"hello".echo(" world")
"hello".echo " world"
Identifier equality
Except for the first letter, identifiers in Nim are compared in a case-insensitive manner, and underscores are ignored.
Example:
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 words 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,
Microsoft Visual C++
Microsoft Visual C++ (MSVC) is a compiler for the C, C++ and C++/CX programming languages by Microsoft. MSVC is proprietary software; it was originally a standalone product but later became a part of Visual Studio and made available in both tri ...
(MSVC),
MinGW, and
GNU Compiler Collection
The GNU Compiler Collection (GCC) is an optimizing compiler produced by the GNU Project supporting various programming languages, hardware architectures and operating systems. The Free Software Foundation (FSF) distributes GCC as free softwar ...
(GCC). The Nim compiler can also emit
C++,
Objective-C
Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXT ...
, and
JavaScript
JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of websites use JavaScript on the client side for webpage behavior, of ...
code to allow easy interfacing with application programming interfaces (
APIs) 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 is a set of compiler and toolchain technologies that can be used to develop a front end for any programming language and a back end for any instruction set architecture. LLVM is designed around a language-independent intermediate repre ...
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:
*
--gc:refc
– This is the default GC. It's a deferred
reference counting
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, refer ...
based
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and ...
with a simple Mark&Sweep backup GC in order to collect cycles. Heaps are thread-local.
*
--gc:markAndSweep
– Simple Mark-And-Sweep based
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and ...
. Heaps are thread-local.
*
--gc:boehm
– Boehm based
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and ...
, it offers a shared heap.
*
--gc:go
–
Go's
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and ...
, useful for interoperability with
Go. Offers a shared heap.
*
--gc:arc
– Plain
reference counting
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, refer ...
with move semantic optimizations, offers a shared heap. It offers deterministic performance for hard realtime systems. Reference cycles cause memory leaks, beware.
*
--gc:orc
– Same as
--gc:arc
but adds a cycle collector based on "trial deletion". Unfortunately, that makes its performance profile hard to reason about so it is less useful for hard real-time systems.
*
--gc:none
– No memory management strategy nor a
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and ...
. Allocated memory is simply never freed, unless manually freed by the developer's code.
Development tools
Bundled
Many tools are bundled with the Nim install package, including:
Nimble
Nimble is the standard
package manager 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 ; also ) is an open standard file format and data interchange format that uses human-readable text to store and transmit data objects consisting of attribute–value pairs and arrays (or other se ...
) 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
Git () is a distributed version control system: tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data in ...
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 sou ...
(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 ( or ) is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged as a Linux distribution, whi ...
,
macOS
macOS (; previously OS X and originally Mac OS X) is a Unix operating system developed and marketed by Apple Inc. since 2001. It is the primary operating system for Apple's Mac computers. Within the market of desktop and la ...
, and
Berkeley Software Distribution
The Berkeley Software Distribution or Berkeley Standard Distribution (BSD) is a discontinued operating system based on Research Unix, developed and distributed by the Computer Systems Research Group (CSRG) at the University of California, Be ...
(BSD).
nimpretty
nimpretty is a source code beautifier, used to format code according to the official Nim style guide.
Testament
Testamentis an advanced automatic Unittests 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 package 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.
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 materials, books or media that are accessible for use and not just for display purposes. A library provides physical (hard copies) or digital access (soft copies) materials, and may be a physical location or a vi ...
which can be used in a C, C++, or JavaScript program.
Language bindings exist for many libraries, including
GTK,
Qt QML,
wxWidgets,
Simple DirectMedia Layer (SDL) 2,
Cairo
Cairo ( ; ar, القاهرة, al-Qāhirah, ) is the capital of Egypt and its largest city, home to 10 million people. It is also part of the largest urban agglomeration in Africa, the Arab world and the Middle East: The Greater Cairo metr ...
,
OpenGL
OpenGL (Open Graphics Library) is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics. The API is typically used to interact with a graphics processing unit (GPU), to achieve hardwa ...
,
Windows API
The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems. The name Windows API collectively refers to several different platform implementations th ...
(WinAPI),
zlib,
libzip
libzip is an open source library for handling zip archives. It is written in portable C and can thus be used on multiple operating systems. It is based on zlib. It is used by PHP'zip extensionfor zip file support and MySQL Workbench. ,
OpenSSL
OpenSSL is a software library for applications that provide secure communications over computer networks against eavesdropping or need to identify the party at the other end. It is widely used by Internet servers, including the majority of HT ...
,
Vulkan and
cURL
cURL (pronounced like "curl", UK: , US: ) is a computer software project providing a library (libcurl) and command-line tool (curl) for transferring data using various network protocols. The name stands for "Client URL".
History
cURL was ...
.
Nim works with
PostgreSQL
PostgreSQL (, ), also known as Postgres, is a free and open-source relational database management system (RDBMS) emphasizing extensibility and SQL compliance. It was originally named POSTGRES, referring to its origins as a successor to the ...
,
MySQL
MySQL () is an 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 relational database ...
, and
SQLite
SQLite (, ) is a database engine written in the C programming language. It is not a standalone app; rather, it is a library that software developers embed in their apps. As such, it belongs to the family of embedded databases. It is the mo ...
databases. Nim can interface with the
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( ...
,
C#,
TypeScript
TypeScript is a free and open source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and adds optional static typing to the language. It is designed for the development of large app ...
,
and
Python programming languages.
Examples
Hello world
The
"Hello, World!" program
A "Hello, World!" program is generally a computer program that ignores any input and outputs or displays a message similar to "Hello, World!". A small piece of code in most general-purpose programming languages, this program is used to illustr ...
in Nim:
echo("Hello, world!")
# Procedures can be called with no parentheses
echo "Hello, World!"
Another version of making a "Hello World" is...
stdout.write("Hello, world!\n")
Factorial
Program to calculate the
factorial
In mathematics, the factorial of a non-negative denoted is the 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 (n-1) \times (n-2) \ ...
of a positive integer using the iterative approach:
import 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 math
echo fac(x)
Reversing a string
A simple demonstration showing many of Nim's features.
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 the 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
GTK3 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 applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
is supported in Nim through
first-class function
In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from ...
s and code without
side effects
In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequenc ...
via the `noSideEffect` pragma, the `func` keyword and the experimental feature `strictFuncs`.
With the `strictFuncs` feature enabled, Nim will perform
side effect
In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequence ...
analysis and raise compilation errors for code that does not obey the contract of producing no
side effects
In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequenc ...
.
Contrary to purely
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
languages, Nim is a
multi-paradigm
Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms.
Some paradigms are concerned mainly with implications for the execution model of the language, suc ...
programming language, so
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
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 functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from ...
s by allowing functions to be stored in variables or passed as parameters to be invoked by other functions.
For example:
import sequtils
let powersOfTwo = @ , 2, 4, 8, 16, 32, 64, 128, 256
echo(powersOfTwo.filter do (x: int) -> bool: x > 32)
echo powersOfTwo.filter(proc (x: int): bool = x > 32)
proc greaterThan32(x: int): bool = x > 32
echo powersOfTwo.filter(greaterThan32)
Produces the output:
@ 4, 128, 256@ 4, 128, 256@ 4, 128, 256
Funcs
The
func
keyword introduces a shortcut for a
noSideEffect
pragma.
func binarySearch a: openArray elem: T): int
Is short for:
proc binarySearch a: openArray elem: T): int
Strict funcs
Since version 1.4, a stricter definition of a "side effect" is available. In addition to the existing rule that a side effect is calling a function with side effects the following rule is also enforced:
Any mutation to an object does count as a side effect if that object is reachable via a parameter that is not declared as a
var
parameter.
For example:
type
Node = ref object
le, ri: Node
data: string
func len(n: Node): int =
# valid: len does not have side effects
var it = n
while it != nil:
inc result
it = it.ri
func mut(n: Node) =
let m = n # is the statement that connected the mutation to the parameter
m.data = "yeah" # the mutation is here
# Error: 'mut' can have side effects
# an object reachable from 'n' is potentially mutated
Object-oriented programming (OOP)
Metaprogramming
Template
This is an example of metaprogramming in Nim using its template facilities.
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.
Generic
Nim supports both constrained and unconstrained generic programming.
Generics may be used in procedures, templates and macros. They are defined after the proc's name in square brackets, as seen below.
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)
In
addThese
,
T
is the generic type, the compiler will accept any values for this function as long as both parameters and the return value are of the same type.
One can further clarify which types the procedure will accept by specifying a type class.
proc addTheseNumbers : SomeNumbera, b: T): T =
a + b
addTheseNumbers
will then only work for types contained in the
SomeNumber
/code>sum type.
Macros
Macros can rewrite parts of the code at compile-time. Nim macros are powerful and can do many operations on the abstract syntax tree.
Here's a simple example, that creates a macro called twice:
import 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 that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of websites use JavaScript on the client side for webpage behavior, of ...
compilation 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
Node.js is an open-source server environment. Node.js is cross-platform and runs on Windows, Linux, Unix, and macOS. Node.js is a back-end JavaScript runtime environment. Node.js runs on the V8 JavaScript Engine and executes JavaScript cod ...
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 locks
var
thr: array ..4,_Thread[tuple[a,b:_int.html" ;"title="uple[a,b:_int.html" ;"title="..4, Thread[tuple[a,b: int">..4, Thread[tuple[a,b: int">uple[a,b:_int.html" ;"title="..4, Thread[tuple[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 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
Nim supports asynchronous IO via the asyncdispatch
module, which adds async/await syntax via the macro system. An example of an asynchronous http
The Hypertext Transfer Protocol (HTTP) 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 We ...
server:
import asynchttpserver, asyncdispatch
var server = newAsyncHttpServer()
proc cb(req: Request) =
await req.respond(Http200, "Hello World")
waitFor server.serve(Port(8080), cb)
Community
Nim has an active community on the self-hosted, self-developed official forum. Further, the project uses a Git repository, bug tracker, and wiki hosted by GitHub
GitHub, Inc. () is an Internet hosting service for software development and version control using Git. It provides the distributed version control of Git plus access control, bug tracking, software feature requests, task management, cont ...
, where the community engages with the language.
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 a virus, the severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2). The first known case was identified in Wuhan, China, in December 2019. The disease quick ...
, with an open call for contributor talks in the form of YouTube
YouTube is a global online video sharing and social media platform headquartered in San Bruno, California. It was launched on February 14, 2005, by Steve Chen, Chad Hurley, and Jawed Karim. It is owned by Google, and is the second mo ...
videos. The conference began with language overviews by Nim developers Andreas Rumpf and Dominik Picheta. Presentation topics included talks about Nim web frameworks, mobile development
Mobile app development is the act or process by which a mobile app is developed for mobile devices, such as personal digital assistants, enterprise digital assistants or mobile phones. These software applications are designed to run on mobile ...
, Internet of things
The Internet of things (IoT) describes physical objects (or groups of such objects) with sensors, processing ability, software and other technologies that connect and exchange data with other devices and systems over the Internet or other com ...
(IoT) devices, and game development
Video game development (or gamedev) is the process of developing a video game. The effort is undertaken by a developer, ranging from a single person to an international team dispersed across the globe. Development of traditional commercial PC ...
, including a talk about writing Nim for Game Boy Advance. NimConf 2020 is available as a YouTube playlist.
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
The O'Reilly Open Source Convention (OSCON) was an American annual convention for the discussion of free and open-source software. It was organized by publisher O'Reilly Media and was held each summer, mostly in Portland, Oregon, from 1999 ...
(OSCON) in 2015. Four speakers represented Nim at Free and Open source Software Developers' European Meeting (FOSDEM
Free and Open source Software Developers' European Meeting (FOSDEM) is a non-commercial, volunteer-organized European event centered on free and open-source software development. It is aimed at developers and anyone interested in the free and ...
) 2020, including the creator of the language, Andreas Rumpf.
See also
* Fat pointer
In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It is commonly employed in, and considered a prime characteristic of, object-oriented ...
* C++
* 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-engine ...
* Go (programming language)
Go is a statically typed, compiled programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson. It is syntactically similar to C, but with memory safety, garbage collection, structural typing, and CSP-style ...
* Rust (programming language)
References
External links
*
*
Information about Nim
on Stack Overflow
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