Nim (programming language)

Nimis ageneral-purpose,multi-paradigm,statically typed,compiledhigh-levelsystemprogramming language,[9]designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant",[10]supportingmetaprogramming,functional,message passing,[11]procedural,andobject-oriented programmingstyles by providing several features such ascompile timecode generation,algebraic data types,aforeign function interface(FFI) withC,C++,Objective-C,andJavaScript,and supporting compiling to those same languages asintermediate representations.

Nim
The Nim crown logo
ParadigmsMulti-paradigm:compiled,concurrent,procedural,imperative,functional,object-oriented,meta
Designed byAndreas Rumpf
DeveloperNim Lang Team[1]
First appeared2008;16 years ago(2008)
Stable release
2.2.0[2]Edit this on Wikidata / 2 October 2024;52 days ago(2 October 2024)
Typing disciplineStatic,[3]strong,[4]inferred,structural
ScopeLexical
Implementation languagePascal(2005–2008)
Nim (2008–present, self-hosted)
PlatformIA-32,x86-64,ARM,Aarch64,RISC-V,PowerPC...[5]
OSCross-platform[6]
LicenseMIT License[7]Edit this on Wikidata
Filename extensions.nim,.nims,.nimble
Websitenim-lang.org
Influenced by
Ada,Modula-3,Lisp,C++,Object Pascal,Python,Oberon,Rust,ParaSail[8]

Description

edit

Nim is statically typed.[12]It supports compile-timemetaprogrammingfeatures such as syntactic macros andterm rewriting macros.[13]Term rewriting macros enablelibraryimplementations 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.[14]Iterators are supported and can be used as first class entities,[13]as can functions, allowing for the use offunctional programmingmethods.Object-oriented programmingis supported byinheritanceandmultiple dispatch.Functions can be generic and overloaded, andgenericsare further enhanced by Nim's support fortype classes.Operator overloadingis also supported.[13]Nim includes multiple tunable memory management strategies, includingtracinggarbage collection,reference counting,andfully manual systems,with the default being deterministicreference countingwith optimizations viamove semanticsandcycle collectionvia trial deletion.[15]

[Nim]... presents a most original design that straddlesPascalandPythonand compiles to C code or JavaScript.[16]

— Andrew Binstock, editor-in-chief ofDr. Dobb's Journal,2014

As of August 2023,Nim compiles to C, C++, JavaScript, Objective-C,[17]and LLVM.[18]

History

edit
Branch Version Release date[19]
0.x Old version, no longer maintained:0.10.2 2014-12-29
Old version, no longer maintained:0.11.2 2015-05-04
Old version, no longer maintained:0.12.0 2015-10-27
Old version, no longer maintained:0.13.0 2016-01-18
Old version, no longer maintained:0.14.2 2016-06-09
Old version, no longer maintained:0.15.2 2016-10-23
Old version, no longer maintained:0.16.0 2017-01-08
Old version, no longer maintained:0.17.2 2017-09-07
Old version, no longer maintained:0.18.0 2018-03-01
Old version, no longer maintained:0.19.6 2019-05-13
Old version, no longer maintained:0.20.2 2019-06-17
1.0 Old version, no longer maintained:1.0.0 2019-09-23
Old version, no longer maintained:1.0.10 2020-10-27
1.2 Old version, no longer maintained:1.2.0 2020-04-03
Old version, no longer maintained:1.2.18 2022-02-09
1.4 Old version, no longer maintained:1.4.0 2020-10-16
Old version, no longer maintained:1.4.8 2021-05-25
1.6 Old version, no longer maintained:1.6.0 2021-10-19
Old version, no longer maintained:1.6.20 2024-04-16
2.0 Old version, no longer maintained:2.0.0 2023-08-01
Old version, yet still maintained:2.0.12 2024-11-01
2.2 Current stable version:2.2.0 2024-10-02
Legend:
Old version, not maintained
Old version, still maintained
Latest version
Latest preview version
Future release
For each 0.x branch, only the latest point release is listed.
For later branches, the first and the latest point release is listed.

Nim's initial development was started in 2005 by Andreas Rumpf. It was originally named Nimrod when the project was made public in 2008.[20]: 4–11 

The first version of the Nimcompilerwas written inPascalusing theFree Pascalcompiler.[21]In 2008, a version of the compiler written in Nim was released.[22]The compiler isfree and open-source software,and is being developed by a community of volunteers working with Andreas Rumpf.[23]The language was officially renamed fromNimrodtoNimwith the release of version 0.10.2 in December 2014.[24]On September 23, 2019, version 1.0 of Nim was released, signifying the maturing of the language and its toolchain. On August 1st, 2023, version 2.0 of Nim was released, signifying the completion, stabilization of, and switch to the ARC/ORC memory model.[25]

Language design

edit

Syntax

edit

The syntax of Nim resembles that ofPython.[26]Code blocks and nesting statements are identified through use ofwhitespace,according to theoffside-rule.Manykeywordsare 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 supportsindentation-based syntax like Python, it introduced additional flexibility. For example, a singlestatementmay span multiple lines if a comma orbinary operatoris 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 easytype 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:

  • 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"
proctimesTwo(i:SomeNumber)=
echoi*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
functwiceIfIsNumber[T:SomeOrdinal](i:T):T=
whenTisSomeNumber:# 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
echotwiceIfIsNumber(67)# Passes an int to the function
echo twiceIfIsNumber(67u8) # Passes an uint8
echotwiceIfIsNumber(true)# Passes a bool (Which is also an Ordinal)

Influence

edit

According to the language creator, Nim was conceived to combine the best parts of Ada typing system,Pythonflexibility, and powerfulLispmacro system.[27]

Nim was influenced by specific characteristics of existing languages, including the following:

Uniform Function Call Syntax

edit

Nim supportsUniform Function Call Syntax(UFCS)[28]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

edit

Nim is almost fully style-insensitive; twoidentifiersare 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.[29]

constuseHttps=true
assertuseHttps==useHttps
assertuseHTTPS==useHttps
assertuse_https==useHttps

Stropping

edit

Thestroppingfeature allows the use of any name for variables or functions, even when the names arereserved wordsfor keywords. An example of stropping is the ability to define a variable namedif,without clashing with the keywordif.Nim's implementation of this is achieved via backticks, allowing any reserved word to be used as an identifier.[30]

typeType=object
`int`:int

let`object`=Type(`int`:9)
assert`object`isType
assert`object`.`int`==9

var`var`=42
let`let`=8
assert`var`+`let`==50

const`assert`=true
assert`assert`

Compiler

edit

The Nim compiler emits fast, optimizedCcode by default. It defers compiling-to-object code to an external C compiler[31]to leverage existing compiler optimization and portability. Many C compilers are supported, includingClang,Microsoft Visual C++(MSVC),MinGW,andGNU Compiler Collection(GCC). The Nim compiler can also emitC++,Objective-C,andJavaScriptcode to allow easy interfacing with application programming interfaces (APIs) written in those languages;[9]developers can simply write in Nim, then compile to any supported language. This also allows writing applications foriOSandAndroid.There is also an unofficialLLVMbackend, allowing use of the Nim compiler in a stand-alone way.[18]

The Nim compiler isself-hosting,meaning it is written in the Nim language.[32]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.[citation needed]

Compiler options

edit

By default, the Nim compiler creates adebugbuild.[33] With the option-d:releaseareleasebuild can be created, which is optimized for speed and contains fewer runtime checks.[33] With the option-d:dangerall runtime checks can be disabled, if maximum speed is desired.[33]

Memory management

edit

Nim supports multiple memory management strategies, including the following:[34]

  • --mm:arc– Automaticreference counting(ARC) withmove semanticsoptimizations, offers a shared heap. It offers fully deterministic performance for hard realtime systems.[35]Reference cycles may cause memory leaks: these may be dealt with by manually annotating{.acyclic.}pragmas or by using--mm:orc.
  • --mm:orc– Same as--mm:arcbut adds a cycle collector (the "O" ) based on "trial deletion".[36]The cycle collector only analyzes types if they are potentially cyclic.
  • --mm:refc– Standard deferredreference countingbasedgarbage collectorwith a simple mark-and-sweep backup GC in order to collect cycles. Heaps are thread-local.
  • --mm:markAndSweep– Simplemark-and-sweepbasedgarbage collector.Heaps are thread-local.
  • --mm:boehmBoehmbasedgarbage collector,it offers a shared heap.
  • --mm:goGo'sgarbage collector,useful for interoperability withGo.Offers a shared heap.
  • --mm:none– No memory management strategy nor agarbage 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.[37]

Development tools

edit

Bundled

edit

Many tools are bundled with the Nim install package, including:

Nimble

edit

Nimble is the standardpackage managerused by Nim to package Nim modules.[38]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.[39]

Nimble packages are defined by.nimblefiles, which contain information about the package version, author, license, description, dependencies, and more.[20]: 132 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) 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, andGithash 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.[20]: 130–131 

c2nim

edit

c2nim is asource-to-source compiler(transcompiler or transpiler) meant to be used onC/C++headers to help generate new Nim bindings.[40]The output is human-readable Nim code that is meant to be edited by hand after the translation process.

koch

edit

koch is a maintenance script that is used to build Nim, and provide HTML documentation.[41]

nimgrep

edit

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.[42]

nimsuggest

edit

nimsuggest is a tool that helps any source code editor query a.nimsource file to obtain useful information like definition of symbols or suggestions for completions.[43]

niminst

edit

niminst is a tool to generate an installer for a Nim program.[44] It creates.msi installers for Windows via Inno Setup, and install and uninstall scripts forLinux,macOS,andBerkeley Software Distribution(BSD).

nimpretty

edit

nimpretty is a source code beautifier, used to format code according to the official Nim style guide.[45]

Testament

edit

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

edit

Some notable tools not included in the Nim distribution include:

choosenim

edit

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.[46]

nimpy

edit

nimpyis a library that enables convenient Python integration in Nim programs.[47]

pixie

edit

pixieis a feature-rich 2D graphics library, similar toCairoor theSkia.It usesSIMDacceleration to speed-up image manipulation drastically. It supports many image formats, blending, masking, blurring, and can be combined with theboxylibrary to do hardware accelerated rendering.

nimterop

edit

nimteropis a tool focused on automating the creation of C/C++ wrappers needed for Nim's foreign function interface.[48]

Libraries

edit

Pure/impure libraries

edit

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

edit

The Nim standard library includes modules for all basic tasks, including:[49]

  • 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

edit

A Nim program can use anylibrarywhich can be used in a C, C++, or JavaScript program.Language bindingsexist for many libraries, includingGTK,[50][51]QtQML,[52]wxWidgets,[53]SDL 2,[54][55]Raylib,[56]Godot,[57]UE5,[58]Cairo,[59]OpenGL,[60]Vulkan,[61]WinAPI,[62]zlib,libzip,OpenSSLandcURL.[63]Nim works withPostgreSQL,MySQL,andSQLitedatabases.

There are open source tools of various degree of support that can be used to interface Nim withLua,[64]Julia,[65]Rust,[66] C#,[67] andPython[68]programming languages or transpile Nim toTypeScript.[69]

Examples

edit

Hello world

edit

The"Hello, World!" programin Nim:

echo("Hello, World!")
# Procedures can be called with no parentheses
echo"Hello, World!"

Another version of "Hello World" can be accomplished by calling thewritefunction with thestdoutstream:

stdout.write("Hello, World!\n")
write(stdout,"Hello, World!\n")

Fibonacci

edit

Several implementations of theFibonacci function,showcasing implicit returns, default parameters, iterators, recursion, and while loops:

procfib(n:Natural):Natural=
ifn<2:
returnn
else:
returnfib(n-1)+fib(n-2)

funcfib2(n:int,a=0,b=1):int=
ifn==0:aelse:fib2(n-1,b,a+b)

iteratorfib3:int=
vara=0
varb=1
whiletrue:
yielda
swapa,b
b+=a

Factorial

edit

Program to calculate thefactorialof a positive integer using the iterative approach, showcasing try/catch error handling and for loops:

importstd/strutils

varn=0
try:
stdout.write"Input positive integer number:"
n=stdin.readline.parseInt
exceptValueError:
raisenewException(ValueError,"You must enter a positive number")

varfact=1
foriin2..n:
fact=fact*i

echofact

Using the module math from Nim's standard library:

importstd/math
echofac(x)

Reversing a string

edit

A simple demonstration showing the implicit result variable and the use of iterators.

procreverse(s:string):string=
foriincountdown(s.high,0):
result.adds[i]

letstr1="Reverse This!"
echo"Reversed:",reverse(str1)

One of Nim's more exotic features is the implicitresultvariable. 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 ofcountdownwhich is an iterator. If an iterator is omitted, the compiler will attempt to use anitemsiterator, if one is defined for the type specified.

Graphical user interface

edit

UsingGTK 3with GObject introspection through thegintromodule:

importgintro/[gtk,glib,gobject,gio]

procappActivate(app:Application)=
letwindow=newApplicationWindow(app)
window.title="GTK3 application with gobject introspection"
window.defaultSize=(400,400)
showAll(window)

procmain=
letapp=newApplication("org.gtk.example")
connect(app,"activate",appActivate)
discardrun(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

edit

Functional programming

edit

Functional programmingis supported in Nim throughfirst-class functionsand code withoutside effectsvia thenoSideEffectpragma or thefunckeyword.[70]Nim will performside effectanalysis and raise compiling errors for code that does not obey the contract of producing noside effectswhen compiled with the experimental featurestrictFuncs,planned to become the default in later versions.[71]

Contrary to purelyfunctional programminglanguages, Nim is amulti-paradigmprogramming language, sofunctional programmingrestrictions are opt-in on a function-by-function basis.

First-class functions

edit

Nim supportsfirst-class functionsby allowing functions to be stored in variables or passed anonymously as parameters to be invoked by other functions.[72]Thestd/sugarmodule provides syntactic sugar for anonymous functions in type declarations and instantiation.

importstd/[sequtils,sugar]

letpowersOfTwo=@[1,2,4,8,16,32,64,128,256]

procfilter[T](s:openArray[T],pred:T->bool):seq[T]=
result=newSeq[T]()
foriin0..<s.len:
ifpred(s[i]):
result.add(s[i])

echopowersOfTwo.filter(proc(x:int):bool=x>32)
# syntactic sugar for the above, provided as a macro from std/sugar
echopowersOfTwo.filter(x=>x>32)

procgreaterThan32(x:int):bool=x>32
echopowersOfTwo.filter(greaterThan32)

Side effects

edit

Side effects of functions annotated with thenoSideEffectpragma 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 ofvarorreftype: this is expected to fail to compile with the currently-experimentalstrictFuncsin the future.[73]Thefunckeyword introduces a shortcut for anoSideEffectpragma.[74]

funcbinarySearch[T](a:openArray[T];elem:T):int
# is short for...
procbinarySearch[T](a:openArray[T];elem:T):int{.noSideEffect.}

{.experimental: "strictFuncs".}

type
Node=refobject
le,ri:Node
data:string

funclen(n:Node):int=
# valid: len does not have side effects
varit=n
whileit!=nil:
incresult
it=it.ri

funcmut(n:Node)=
letm=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

Function composition

edit

Uniform function call syntaxallows for thechaining of arbitrary functions,perhaps best exemplified with thestd/sequtilslibrary.[75]

importstd/[sequtils,sugar]

letnumbers=@[1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
# a and b are special identifiers in the foldr macro
echonumbers.filter(x=>x>3).deduplicate.foldr(a+b)# 30

Algebraic data types and pattern matching

edit

Nim has support forproduct typesvia theobjecttype, and forsum typesviaobject variants:raw representations oftagged unions,with an enumerated type tag that must besafely matched uponbefore fields of variants can be accessed.[76]These types can becomposed algebraically.Structural pattern matchingis available, but regulated to macros in various third-party libraries.[77]

importstd/tables

type
Value=uint64
Ident=string
ExprKind=enum
Literal,Variable,Abstraction,Application
Expr=refobject
casekind:ExprKind
ofLiteral:
litIdent:Value
ofVariable:
varIdent:Ident
ofAbstraction:
paramAbs:Ident
funcAbs:Expr
ofApplication:
funcApp,argApp:Expr

funceval(expr:Expr,context:varTable[Ident,Value]):Value=
caseexpr.kind
ofLiteral:
returnexpr.litIdent
ofVariable:
returncontext[expr.varIdent]
ofApplication:
caseexpr.funcApp.kind
ofAbstraction:
context[expr.funcApp.paramAbs]=expr.argApp.eval(context)
returnexpr.funcAbs.eval(context)
else:
raisenewException(ValueError,"Invalid expression!")
else:
raisenewException(ValueError,"Invalid expression!")

Object-oriented programming

edit

Despite being primarily an imperative and functional language, Nim supports various features for enabling object-oriented paradigms.[78][79]

Subtyping and inheritance

edit

Nim supports limited inheritance by use ofref objectsand theofkeyword.[79]To enable inheritance, any initial ( "root" ) object must inherit fromRootObj.Inheritance is of limited use within idiomatic Nim code: with the notable exception of Exceptions.[80]

typeAnimal=refobjectofRootObj
name:string
age:int
typeDog=refobjectofAnimal
typeCat=refobjectofAnimal

varanimals:seq[Animal]=@[]
animals.add(Dog(name:"Sparky",age:10))
animals.add(Cat(name:"Mitten",age:10))

forainanimals:
assertaofAnimal

Subtyping relations can also be queried with theofkeyword.[79]

Method calls and encapsulation

edit

Nim'suniform function call syntaxenables 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.

typeSocket*=refobject
host:int# private, lacks export marker

# getter of host address
prochost*(s:Socket):int=s.host

# setter of host address
proc`host=`*(s:varSocket,value:int)=
s.host=value

vars:Socket
news
asserts.host==0# same as host(s), s.host()
s.host=34# same as `host=`(s, 34)

Dynamic dispatch

edit

Static dispatchis preferred, more performant, and standard even among method-looking routines.[79]Nonetheless, if dynamic dispatch is so desired, Nim provides themethodkeyword for enablingdynamic dispatchon reference types.

importstd/strformat

type
Person=refobjectofRootObj
name:string
Student=refobjectofPerson
Teacher=refobjectofPerson

methodintroduce(a:Person)=
raisenewException(CatchableError,"Method without implementation override")

methodintroduce(a:Student)=
echo&"I am a student named {a.name}!"

methodintroduce(a:Teacher)=
echo&"I am a teacher named {a.name}!"

letpeople:seq[Person]=@[Teacher(name:"Alice"),Student(name:"Bob")]
forpersoninpeople:
person.introduce()

Metaprogramming

edit

Templates

edit

Nim supports simple substitution on the abstract syntax tree via its templates.

templategenType(name,fieldname:untyped,fieldtype:typedesc)=
type
name=object
fieldname:fieldtype

genType(Test,foo,int)

varx=Test(foo:4566)
echo(x.foo)# 4566

ThegenTypeis invoked at compile-time and aTesttype is created.

Generics

edit

Nim supports both constrained and unconstrained generic programming. Generics may be used in procedures, templates and macros. Unconstrained generic identifiers (Tin this example) are defined after the routine's name in square brackets. Constrained generics can be placed on generic identifiers, or directly on parameters.

procaddThese[T](a,b:T):T=a+b
echoaddThese(1,2)# 3 (of int type)
echoaddThese(uint81,uint82)# 3 (of uint8 type)

# we don't want to risk subtracting unsigned numbers!
procsubtractThese[T:SomeSignedInt|float](a,b:T):T=a-b
echosubtractThese(1,2)# -1 (of int type)

importstd/sequtils

# constrained generics can also be directly on the parameters
proccompareThese[T](a,b:string|seq[T]):bool=
for(i,j)inzip(a,b):
ifi!=j:
returnfalse

One can further clarify which types the procedure will accept by specifying a type class (in the example above,SomeSignedInt).[81]

Macros

edit

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.[82]

Here's a simple example that creates a macro to call code twice:

importstd/macros

macrotwice(arg:untyped):untyped=
result=quotedo:
`arg`
`arg`

twiceecho"Hello world!"

Thetwicemacro 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)

edit

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.[20]: 226 

The following program shows the ease with which external C code can be used directly in Nim.

procprintf(formatstr:cstring){.header:"<stdio.h>", varargs.}

printf("%s %d\n","foo",5)

In this code theprintffunction is imported into Nim and then used.

Basic example using 'console.log' directly for theJavaScriptcompiling target:

proclog(args:any){.importjs:"console.log(@)", varargs.}
log(42,"z",true,3.14)

The JavaScript code produced by the Nim compiler can be executed withNode.jsor a web browser.

Parallelism

edit

To activate threading support in Nim, a program should be compiled with--threads:oncommand 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.

importstd/locks

var
thr:array[0..4,Thread[tuple[a,b:int]]]
L:Lock

procthreadFunc(interval:tuple[a,b:int]){.thread.}=
foriininterval.a..interval.b:
acquire(L)# lock stdout
echoi
release(L)

initLock(L)

foriin0..high(thr):
createThread(thr[i],threadFunc,(i*10,i*10+5))
joinThreads(thr)

Nim also has achannelsmodule that simplifies passing data between threads.

importstd/os

type
CalculationTask=object
id*:int
data*:int

CalculationResult=object
id*:int
result*:int

vartask_queue:Channel[CalculationTask]
varresult_queue:Channel[CalculationResult]

procworkerFunc(){.thread.}=
result_queue.open()

whiletrue:
vartask=task_queue.recv()
result_queue.send(CalculationResult(id:task.id,result:task.data*2))

varworkerThread:Thread[void]
createThread(workerThread,workerFunc)

task_queue.open()
task_queue.send(CalculationTask(id:1,data:13))
task_queue.send(CalculationTask(id:2,data:37))

whiletrue:
echo"got result:",repr(result_queue.recv())

Concurrency

edit

Asynchronous IO is supported either via theasyncdispatchmodule in the standard library or the externalchronoslibrary.[83]Both libraries addasync/awaitsyntax via the macro system, without need for special language support. An example of an asynchronousHTTPserver:

importstd/[asynchttpserver,asyncdispatch]
# chronos could also be alternatively used in place of asyncdispatch,
# with no other changes.

varserver=newAsyncHttpServer()
proccb(req:Request){.async.}=
awaitreq.respond(Http200,"Hello World")

waitForserver.serve(Port(8080),cb)

Community

edit

Online

edit

Nim has an active community on the self-hosted, self-developed official forum.[84]Further, the project uses a Git repository, bug tracker, RFC tracker, and wiki hosted byGitHub,where the community engages with the language.[85]There are also official online chat rooms, bridged betweenIRC,Matrix,Discord,Gitter,andTelegram.[86]

Conventions

edit

The first Nim conference, NimConf, took place on June 20, 2020. It was held digitally due toCOVID-19,with an open call for contributor talks in the form ofYouTubevideos.[87]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(IoT) devices, andgame development,including a talk about writing Nim forGame Boy Advance.[88]NimConf 2020 is available as a YouTube playlist.[89]NimConf 2021 occurred the following year, was also held digitally, and included talks aboutgame development,REPLs,real-time operating systems,Nim in the industry,object-relational mapping(ORM),fuzzing,language design,andgraphics libraries.[90]

In addition to official conferences, Nim has been featured at various other conventions. A presentation on Nim was given at theO'Reilly Open Source Convention(OSCON) in 2015.[91][92][93]Four speakers represented Nim atFOSDEM2020, including the creator of the language, Andreas Rumpf.[94]At FOSDEM 2022, Nim hosted their own developer room virtually due to theCOVID-19 pandemic.[95]Talks were held onconcurrency,embedded programming,programming forGPUs,entity-component systems,game development,rules engines,Pythoninterop,andmetaprogramming.[96]

See also

edit

References

edit
  1. ^"Contributors to nim-lang/Nim".GitHub.Retrieved2022-03-23.
  2. ^https://github.com/nim-lang/Nim/releases/tag/v2.2.0.{{cite web}}:Missing or empty|title=(help)
  3. ^"Nim by example".GitHub.Retrieved2014-07-20.
  4. ^Караджов, Захари; Станимиров, Борислав (2014).Метапрограмиране с Nimrod.VarnaConf(in Bulgarian).Retrieved2014-07-27.
  5. ^"Packaging Nim".Retrieved2022-03-23.
  6. ^"Install Nim".Retrieved2018-10-12.
  7. ^"copying.txt".GitHub.
  8. ^abRumpf, Andreas (2017-10-19)."Nim without GC".Araq's Musings.Retrieved2020-09-01.
  9. ^abRumpf, Andreas (2014-02-11)."Nimrod: A new systems programming language".Dr. Dobb's Journal.Retrieved2014-07-20.
  10. ^"The Nim Programming Language".Nim-lang.org.Retrieved2014-07-20.
  11. ^"FAQ".nim-lang.org.Retrieved2015-03-27.
  12. ^Kehrer, Aaron (akehrer) (2015-01-05)."Nim Syntax".GitHub.Retrieved2015-01-05.
  13. ^abc"Nim Manual".Nim-lang.org.Retrieved2014-07-20.
  14. ^"Strangeloop Nim presentation".Archived fromthe originalon 2014-07-13.Retrieved2015-04-30.
  15. ^"Nim's Memory Management".nim-lang.org.Retrieved2023-08-17.
  16. ^Binstock, Andrew (2014-01-07)."The Rise And Fall of Languages in 2013".Dr. Dobb's Journal.Retrieved2018-10-08.
  17. ^Nim Compiler User Guide
  18. ^abSieka, Jacek (2020-07-18),arnetheduck/nlvm,retrieved2020-07-21
  19. ^"Nim Releases".Nim Project.Retrieved2020-01-26.
  20. ^abcdPicheta, Dominik (2017).Nim in Action.Manning Publications.ISBN978-1617293436.
  21. ^"Nim Pascal Sources".GitHub.Retrieved2013-04-05.
  22. ^"News".Nim-lang.org.Archivedfrom the original on 2016-06-26.Retrieved2016-06-11.
  23. ^"Contributors".GitHub.Retrieved2013-04-05.
  24. ^Picheta, Dominik (2014-12-29)."Version 0.10.2 released".Nim-lang.org.Retrieved2018-10-17.
  25. ^"Nim v2.0 released".Nim Programming Language.Retrieved2023-08-17.
  26. ^Yegulalp, Serdar (2017-01-16)."Nim language draws from best of Python, Rust, Go, and Lisp".InfoWorld.
  27. ^Interview with Nim language creator Andreas Rumpf,2020-03-09,retrieved2023-10-15
  28. ^"Nim Manual: Method call syntax".Retrieved2018-10-12.
  29. ^"Nim Manual: Identifier Equality".nim-lang.org.Retrieved2023-08-17.
  30. ^Picheta, Dominik (dom96); Wetherfordshire, Billingsly (fowlmouth); Felsing, Dennis (def-); Raaf, Hans (oderwat); Dunn, Christopher (cdunn2001); wizzardx (2017-10-25)."Tips and tricks".GitHub.Retrieved2018-10-17.{{cite web}}:CS1 maint: numeric names: authors list (link)
  31. ^Rumpf, Andreas (2014-01-15).Nimrod: A New Approach to Metaprogramming.InfoQ.Event occurs at 2:23.Retrieved2014-07-20.
  32. ^Rumpf, Andreas (2018-10-12)."Nim Compiling".GitHub.Retrieved2018-10-17.
  33. ^abc"Nim Compiler User Guide".
  34. ^"Nim's Memory Management".nim-lang.org.Retrieved2024-07-28.
  35. ^"Introduction to ARC/ORC in Nim".Nim Programming Language.Retrieved2023-08-17.
  36. ^"ORC - Vorsprung durch Algorithmen".Nim Programming Language.Retrieved2023-08-17.
  37. ^"Nim v2.0 released".Nim Programming Language.Retrieved2023-08-17.
  38. ^"Nimble".GitHub.Retrieved2018-10-12.
  39. ^"Nim v0.12.0 release".GitHub.Retrieved2020-11-28.
  40. ^"c2nim".GitHub.Retrieved2018-10-12.
  41. ^"Nim maintenance script".nim-lang.org.Retrieved2021-11-16.
  42. ^"nimgrep User's manual".nim-lang.org.Retrieved2021-11-16.
  43. ^"Nim IDE Integration Guide".nim-lang.org.Retrieved2021-11-16.
  44. ^"niminst User's manual".nim-lang.org.Retrieved2021-11-16.
  45. ^"Tools available with Nim".nim-lang.org.2021-10-19.Archivedfrom the original on 2015-05-09.Retrieved2022-02-18.
  46. ^"choosenim".GitHub.Retrieved2018-10-12.
  47. ^Glukhov, Yuriy (2021-11-12),nimpy,retrieved2021-11-16
  48. ^nimterop/nimterop,nimterop, 2021-11-12,retrieved2021-11-16
  49. ^Nim Standard Library
  50. ^Installation,The Nim programming language, 2021-09-25,retrieved2021-11-16
  51. ^StefanSalewski (2021-11-15),High level GTK4 and GTK3 bindings for the Nim programming language,retrieved2021-11-16
  52. ^"NimQml".GitHub.2022-11-10.
  53. ^"WxNim".GitHub.2022-11-29.
  54. ^SDL2 for Nim,The Nim programming language, 2021-10-26,retrieved2021-11-16
  55. ^Arabadzhi, Vladimir (2021-11-15),sdl2_nim 2.0.14.2,retrieved2021-11-16
  56. ^"naylib".GitHub.2024-07-28.
  57. ^"godot-nim".GitHub.2024-07-28.
  58. ^"NimForUE".GitHub.2024-07-28.
  59. ^Cairo,The Nim programming language, 2021-10-05,retrieved2021-11-16
  60. ^opengl,The Nim programming language, 2021-11-14,retrieved2021-11-16
  61. ^"vulkan".GitHub.2024-07-28.
  62. ^Ward (2021-11-15),Winim,retrieved2021-11-16
  63. ^"Nim Standard Library".Nim documentation.Archived fromthe originalon 2015-04-06.Retrieved2015-04-04.
  64. ^Lim, Andri (jangko) (2018-10-17)."nimLUA".GitHub.Retrieved2018-10-17.
  65. ^"NimJL".GitHub.2022-08-24.
  66. ^"Nbindgen".GitHub.2022-11-17.
  67. ^"cs2nim".GitHub.2022-10-10.
  68. ^Glukhov, Yuriy (2020-07-20),yglukhov/nimpy,retrieved2020-07-21
  69. ^"ts2nim".GitHub.2022-11-21.
  70. ^"Nim Manual".nim-lang.org.Retrieved2021-07-10.
  71. ^"Nim Forum: Update on strict funcs".forum.nim-lang.org.Retrieved2023-08-17.
  72. ^"Nim by Example - First Class Functions".
  73. ^"Nim Experimental Features: Strict Funcs".
  74. ^"Nim Manual: Func".
  75. ^"std/sequtils".nim-lang.org.Retrieved2023-08-17.
  76. ^"Nim Manual: Object variants".nim-lang.org.Retrieved2023-08-17.
  77. ^"src/fusion/matching".nim-lang.github.io.Retrieved2023-08-17.
  78. ^"Nim Tutorial (Part II): Object Oriented Programming".nim-lang.org.Retrieved2023-08-17.
  79. ^abcd"Nim by Example - Object Oriented Programming".nim-by-example.github.io.Retrieved2023-08-17.
  80. ^"system/exceptions".nim-lang.org.Retrieved2023-08-17.
  81. ^"Nim Manual: Type Classes".nim-lang.org.Retrieved2020-07-21.
  82. ^"Nim Tutorial (Part III)".nim-lang.org.Retrieved2023-08-17.
  83. ^Chronos - An efficient library for asynchronous programming,Status, 2023-08-14,retrieved2023-08-17
  84. ^"Nim Forum".nim-lang.org.Retrieved2015-05-04.
  85. ^"Primary source code repository and bug tracker".GitHub.Retrieved2015-05-04.
  86. ^"Community".Nim Programming Language.Retrieved2023-08-17.
  87. ^"Nim Online Conference 2020".Nim.Retrieved2020-11-28.
  88. ^"NimConf 2020".Nim.Retrieved2023-08-17.
  89. ^"NimConf 2020 Playlist".YouTube.Retrieved2020-11-28.
  90. ^"NimConf 2021".NimConf 2021.Retrieved2023-08-17.
  91. ^"Nim at OSCON 2015".O'Reilly Open Source Convention(OSCON).O'Reilly Media. 2015-07-20. Archived fromthe originalon 2015-10-06.Retrieved2018-10-17.
  92. ^Rumpf, Andreas; Swartz, Jason; Harrison, Matt."Essential Languages: Nim, Scala, Python".O’Reilly.O'Reilly Media.Retrieved2018-10-17.
  93. ^Rumpf, Andreas (2015-10-26).OSCON 2015 – Nim: An Overview.YouTube(Video).Retrieved2018-10-12.
  94. ^"Events".fosdem.org.Retrieved2020-02-17.
  95. ^"Nim Devroom at FOSDEM 2022 - Call for Participation".Nim Programming Language.Retrieved2023-08-17.
  96. ^"Nim Programming Language devroom".archive.fosdem.org.Retrieved2023-08-17.
edit