Nim (programming language)

Last updated

Nim
Nim logo.svg
The Nim crown logo
Paradigms Multi-paradigm: compiled, concurrent, procedural, imperative, functional, object-oriented, meta
Designed by Andreas Rumpf
Developer Nim Lang Team [1]
First appeared2008;16 years ago (2008)
Stable release
2.0.4 [2]   OOjs UI icon edit-ltr-progressive.svg / 16 April 2024;7 days ago (16 April 2024)
Typing discipline Static, [3] strong, [4] inferred, structural
Scope Lexical
Implementation languageNim (self-hosted)
Platform IA-32, x86-64, ARM, Aarch64, RISC-V, PowerPC ... [5]
OS Cross-platform [6]
License MIT License [7]   OOjs UI icon edit-ltr-progressive.svg
Filename extensions .nim, .nims, .nimble
Website nim-lang.org
Influenced by
Ada, Modula-3, Lisp, C++, Object Pascal, Python, Oberon, Rust, ParaSail [8]

Nim is a general-purpose, multi-paradigm, statically typed, compiled high-level systems programming language, [9] designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant", [10] supporting metaprogramming, functional, message passing, [11] procedural, and object-oriented programming styles by providing several features such as compile time code generation, algebraic data types, a foreign function interface (FFI) with C, C++, Objective-C, and JavaScript, and supporting compiling to those same languages as intermediate representations.

Contents

Description

Nim is statically typed. [12] It supports compile-time metaprogramming features such as syntactic macros and term rewriting macros. [13] Term rewriting macros enable library 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. [14] Iterators are supported and can be used as first class entities, [13] as can functions, allowing for the use of functional programming methods. Object-oriented programming is supported by inheritance and multiple dispatch. Functions can be generic and overloaded, and generics are further enhanced by Nim's support for type classes. Operator overloading is also supported. [13] 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. [15]

[Nim] ... presents a most original design that straddles Pascal and Python and compiles to C code or JavaScript. [16]

Andrew Binstock, editor-in-chief of Dr. Dobb's Journal, 2014

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

History

BranchVersionRelease date [19]
0.xOld version, no longer maintained: 0.10.22014-12-29
Old version, no longer maintained: 0.11.22015-05-04
Old version, no longer maintained: 0.12.02015-10-27
Old version, no longer maintained: 0.13.02016-01-18
Old version, no longer maintained: 0.14.22016-06-09
Old version, no longer maintained: 0.15.22016-10-23
Old version, no longer maintained: 0.16.02017-01-08
Old version, no longer maintained: 0.17.22017-09-07
Old version, no longer maintained: 0.18.02018-03-01
Old version, no longer maintained: 0.19.62019-05-13
Old version, no longer maintained: 0.20.22019-06-17
1.0Old version, no longer maintained: 1.0.02019-09-23
Old version, no longer maintained: 1.0.102020-10-27
1.2Old version, no longer maintained: 1.2.02020-04-03
Old version, no longer maintained: 1.2.182022-02-09
1.4Old version, no longer maintained: 1.4.02020-10-16
Old version, no longer maintained: 1.4.82021-05-25
1.6Old version, no longer maintained: 1.6.02021-10-19
Older version, yet still maintained: 1.6.202024-04-16
2.0Old version, no longer maintained: 2.0.02023-08-01
Current stable version: 2.0.42024-04-16
Legend:
Old version
Older 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 Nim compiler was written in Pascal using the Free Pascal compiler. [21] In 2008, a version of the compiler written in Nim was released. [22] The compiler is free and open-source software, and is being developed by a community of volunteers working with Andreas Rumpf. [23] The language was officially renamed from Nimrod to Nim with 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

Syntax

The syntax of Nim resembles that of Python. [26] 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, 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:

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 OrdinalfunctwiceIfIsNumber[T:SomeOrdinal](i:T):T=whenTisSomeNumber:# A `when` is an `if` evaluated during compile timeresult=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 typeresult=(i.int*2).T
echotwiceIfIsNumber(67)# Passes an int to the function echo twiceIfIsNumber(67u8) # Passes an uint8echotwiceIfIsNumber(true)# Passes a bool (Which is also an Ordinal)

Influence

According to the language creator, Nim was conceived to combine the best parts of Ada typing system, Python flexibility, and powerful Lisp macro system. [27]

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

Uniform Function Call Syntax

Nim supports Uniform 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".echoecho("hello"," world")"hello".echo(" world")"hello".echo" world"

Identifier equality

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

constuseHttps=trueassertuseHttps==useHttpsassertuseHTTPS==useHttpsassertuse_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. [30]

typeType=object`int`:intlet`object`=Type(`int`:9)assert`object`isTypeassert`object`.`int`==9var`var`=42let`let`=8assert`var`+`let`==50const`assert`=trueassert`assert`

Compiler

The Nim compiler emits fast, optimized C code 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, including Clang, Microsoft Visual C++ (MSVC), MinGW, and GNU Compiler Collection (GCC). The Nim compiler can also emit C++, Objective-C, and JavaScript code 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 for iOS and Android. There is also an unofficial LLVM backend, allowing use of the Nim compiler in a stand-alone way. [18]

The Nim compiler is self-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

By default, the Nim compiler creates a debug build. [33] With the option -d:release a release build can be created, which is optimized for speed and contains fewer runtime checks. [33] With the option -d:danger all runtime checks can be disabled, if maximum speed is desired. [33]

Memory management

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

As of Nim 2.0, ORC is the default GC. [37]

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. [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 .nimble files, 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, 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. [20] :130–131

c2nim

c2nim is a source-to-source compiler (transcompiler or transpiler) meant to be used on C/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

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

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

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

niminst

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 for Linux, macOS, and Berkeley Software Distribution (BSD).

nimpretty

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

Testament

Testament is 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

choosenim was 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

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

pixie

pixie is a feature-rich 2D graphics library, similar to Cairo or the Skia. It uses SIMD acceleration to speed-up image manipulation drastically. It supports many image formats, blending, masking, blurring, and can be combined with the boxy library to do hardware accelerated rendering.

nimterop

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

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: [49]

Use of other libraries

A Nim program can use any library which can be used in a C, C++, or JavaScript program. Language bindings exist for many libraries, including GTK, [50] [51] Qt QML, [52] wxWidgets, [53] SDL 2, [54] [55] Cairo, [56] OpenGL, [57] WinAPI, [58] zlib, libzip, OpenSSL, Vulkan [59] and cURL. [60] Nim works with PostgreSQL, MySQL, and SQLite databases.

There are open source tools of various degree of support that can be used to interface Nim with Lua, [61] Julia, [62] Rust, [63] C#, [64] and Python [65] programming languages or transpile Nim to TypeScript. [66]

Examples

Hello world

The "Hello, World!" program in Nim:

echo("Hello, World!")# Procedures can be called with no parenthesesecho"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:

procfib(n:Natural):Natural=ifn<2:returnnelse: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=0varb=1whiletrue:yieldaswapa,bb+=a

Factorial

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

importstd/strutilsvarn=0try:stdout.write"Input positive integer number: "n=stdin.readline.parseIntexceptValueError:raisenewException(ValueError,"You must enter a positive number")varfact=1foriin2..n:fact=fact*iechofact

Using the module math from Nim's standard library:

importstd/mathechofac(x)

Reversing a string

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 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 the gintro module:

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

Functional programming

Functional programming is supported in Nim through first-class functions and code without side effects via the noSideEffect pragma or the func keyword. [67] Nim will perform side effect analysis and raise compilation errors for code that does not obey the contract of producing no side effects when compiled with the experimental feature strictFuncs, planned to become the default in later versions. [68]

Contrary to purely functional programming languages, Nim is a multi-paradigm programming language, so functional programming restrictions are opt-in on a function-by-function basis.

First-class functions

Nim supports first-class functions by allowing functions to be stored in variables or passed anonymously as parameters to be invoked by other functions. [69] The std/sugar module 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/sugarechopowersOfTwo.filter(x=>x>32)procgreaterThan32(x:int):bool=x>32echopowersOfTwo.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. [70] The func keyword introduces a shortcut for a noSideEffect pragma. [71]

<syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">func binarySearch[T](a: openArray[T]; elem: T): int</syntaxhighlight> # is short for... <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">proc binarySearch[T](a: openArray[T]; elem: T): int</syntaxhighlight> {.noSideEffect.}  {.experimental: "strictFuncs".}  <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">type</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">Node = ref object</syntaxhighlight>     <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">le, ri: Node</syntaxhighlight>     <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">data: string</syntaxhighlight>  <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">func len(n: Node): int =</syntaxhighlight>   # valid: len does not have side effects   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">var it = n</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">while it != nil:</syntaxhighlight>     <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">inc result</syntaxhighlight>     <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">it = it.ri</syntaxhighlight>  <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">func mut(n: Node) =</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">let m = n # is the statement that connected the mutation to the parameter</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1">m.data = "yeah" # the mutation is here</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1"># Error: 'mut' can have side effects</syntaxhighlight>   <syntaxhighlight lang="nim" class="" id="" style="background:none; border:none; color:inherit; padding: 0px 0px;" inline="1"># an object reachable from 'n' is potentially mutated</syntaxhighlight>

Function composition

Uniform function call syntax allows for the chaining of arbitrary functions, perhaps best exemplified with the std/sequtils library. [72]

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 macroechonumbers.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 unions, with an enumerated type tag that must be safely matched upon before fields of variants can be accessed. [73] These types can be composed algebraically. Structural pattern matching is available, but regulated to macros in various third-party libraries. [74]

importstd/tablestypeValue=uint64Ident=stringExprKind=enumLiteral,Variable,Abstraction,ApplicationExpr=refobjectcasekind:ExprKindofLiteral:litIdent:ValueofVariable:varIdent:IdentofAbstraction:paramAbs:IdentfuncAbs:ExprofApplication:funcApp,argApp:Exprfunceval(expr:Expr,context:varTable[Ident,Value]):Value=caseexpr.kindofLiteral:returnexpr.litIdentofVariable:returncontext[expr.varIdent]ofApplication:caseexpr.funcApp.kindofAbstraction: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

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

Subtyping and inheritance

Nim supports limited inheritance by use of ref objects and the of keyword. [76] 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. [77]

typeAnimal=refobjectofRootObjname:stringage:inttypeDog=refobjectofAnimaltypeCat=refobjectofAnimalvaranimals: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 the of keyword. [76]

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.

typeSocket*=refobjecthost:int# private, lacks export marker# getter of host addressprochost*(s:Socket):int=s.host# setter of host addressproc`host=`*(s:varSocket,value:int)=s.host=valuevars:Socketnewsasserts.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. [76] Nonetheless, if dynamic dispatch is so desired, Nim provides the method keyword for enabling dynamic dispatch on reference types.

importstd/strformattypePerson=refobjectofRootObjname:stringStudent=refobjectofPersonTeacher=refobjectofPersonmethodintroduce(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

Templates

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

templategenType(name,fieldname:untyped,fieldtype:typedesc)=typename=objectfieldname:fieldtypegenType(Test,foo,int)varx=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.

procaddThese[T](a,b:T):T=a+bechoaddThese(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-bechosubtractThese(1,2)# -1 (of int type)importstd/sequtils# constrained generics can also be directly on the parametersproccompareThese[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). [78]

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

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

importstd/macrosmacrotwice(arg:untyped):untyped=result=quotedo:`arg``arg`twiceecho"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. [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 the printf function is imported into Nim and then used.

Basic example using 'console.log' directly for the JavaScript compilation 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 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.

importstd/locksvarthr:array[0..4,Thread[tuple[a,b:int]]]L:LockprocthreadFunc(interval:tuple[a,b:int]){.thread.}=foriininterval.a..interval.b:acquire(L)# lock stdoutechoirelease(L)initLock(L)foriin0..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.

importstd/ostypeCalculationTask=objectid*:intdata*:intCalculationResult=objectid*:intresult*:intvartask_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

Asynchronous IO is supported either via the asyncdispatch module in the standard library or the external chronos library. [80] Both libraries add async/await syntax via the macro system, without need for special language support. An example of an asynchronous HTTP server:

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

Online

Nim has an active community on the self-hosted, self-developed official forum. [81] Further, the project uses a Git repository, bug tracker, RFC tracker, and wiki hosted by GitHub, where the community engages with the language. [82] There are also official online chat rooms, bridged between IRC, Matrix, Discord, Gitter, and Telegram. [83]

Conventions

The first Nim conference, NimConf, took place on June 20, 2020. It was held digitally due to COVID-19, with an open call for contributor talks in the form of YouTube videos. [84] 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, and game development, including a talk about writing Nim for Game Boy Advance. [85] NimConf 2020 is available as a YouTube playlist. [86] NimConf 2021 occurred the following year, was also held digitally, and included talks about game development, REPLs, real-time operating systems, Nim in the industry, object-relational mapping (ORM), language design, and graphics libraries. [87]

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. [88] [89] [90] Four speakers represented Nim at FOSDEM 2020, including the creator of the language, Andreas Rumpf. [91] At FOSDEM 2022, Nim hosted their own developer room virtually due to the COVID-19 pandemic. [92] Talks were held on concurrency, embedded programming, programming for GPUs, entity-component systems, game development, rules engines, Python interop, and metaprogramming. [93]

See also

Related Research Articles

<span class="mw-page-title-main">D (programming language)</span> Multi-paradigm system 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-engineering of C++, D is now a very different language drawing inspiration from other high-level programming languages, notably Java, Python, Ruby, C#, and Eiffel.

In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

Harbour is a computer programming language, primarily used to create database/business programs. It is a modernised, open source and cross-platform version of the older Clipper system, which in turn developed from the dBase database market of the 1980s and 1990s.

In computer science, function composition is an act or mechanism to combine simple functions to build more complicated ones. Like the usual composition of functions in mathematics, the result of each function is passed as the argument of the next, and the result of the last one is the result of the whole.

Haxe is a high-level cross-platform programming language and compiler that can produce applications and source code for many different computing platforms from one code-base. It is free and open-source software, released under the MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.

C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

<span class="mw-page-title-main">Vala (programming language)</span> Programming language

Vala is an object-oriented programming language with a self-hosting compiler that generates C code and uses the GObject system.

The syntax and semantics of PHP, a programming language, form a set of rules that define how a PHP program can be written and interpreted.

<span class="mw-page-title-main">Go (programming language)</span> Programming language

Go is a statically typed, compiled high-level programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson. It is syntactically similar to C, but also has memory safety, garbage collection, structural typing, and CSP-style concurrency. It is often referred to as Golang because of its former domain name, golang.org, but its proper name is Go.

<span class="mw-page-title-main">Rust (programming language)</span> General-purpose programming language

Rust is a multi-paradigm, general-purpose programming language that emphasizes performance, type safety, and concurrency. It enforces memory safety—meaning that all references point to valid memory—without a garbage collector. To simultaneously enforce memory safety and prevent data races, its "borrow checker" tracks the object lifetime of all references in a program during compilation.

Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented, aspect-oriented, reflective and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.

In computer programming, string interpolation is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple template processing or, in formal terms, a form of quasi-quotation. The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current context.

<span class="mw-page-title-main">ParaSail (programming language)</span>

Parallel Specification and Implementation Language (ParaSail) is an object-oriented parallel programming language. Its design and ongoing implementation is described in a blog and on its official website.

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 related to the concept of a coroutine and is often implemented using similar techniques, and is primarily intended to provide opportunities for the program to execute other code while waiting for a long-running, asynchronous task to complete, usually represented by promises or similar data structures. The feature is found in C#, C++, Python, F#, Hack, Julia, Dart, Kotlin, Rust, Nim, JavaScript, Swift and Zig.

Swift is a high-level general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. and the open-source community. Swift compiles to machine code, as it is an LLVM-based compiler. Swift was first released in June 2014, and the Swift toolchain has shipped in Xcode since version 6, released in 2014.

Ballerina is an open source general-purpose programming language designed by WSO2 for cloud-era application programmers.

<span class="mw-page-title-main">Zig (programming language)</span> A general-purpose programming language, toolchain to build Zig/C/C++ code

Zig is an imperative, general-purpose, statically typed, compiled system programming language designed by Andrew Kelley. It is intended to be a successor to the C programming language, with the intention of being even smaller and simpler to program in while also offering more functionality.

References

  1. "Contributors to nim-lang/Nim". GitHub . Retrieved 2022-03-23.
  2. Error: Unable to display the reference properly. See the documentation for details.
  3. "Nim by example". GitHub . Retrieved 2014-07-20.
  4. Караджов, Захари; Станимиров, Борислав (2014). Метапрограмиране с Nimrod. VarnaConf (in Bulgarian). Retrieved 2014-07-27.
  5. "Packaging Nim" . Retrieved 2022-03-23.
  6. "Install Nim" . Retrieved 2018-10-12.
  7. "copying.txt". GitHub.
  8. 1 2 Rumpf, Andreas (2017-10-19). "Nim without GC". Araq's Musings. Retrieved 2020-09-01.
  9. 1 2 Rumpf, Andreas (2014-02-11). "Nimrod: A new systems programming language". Dr. Dobb's Journal . Retrieved 2014-07-20.
  10. "The Nim Programming Language". Nim-lang.org. Retrieved 2014-07-20.
  11. "FAQ". nim-lang.org. Retrieved 2015-03-27.
  12. Kehrer, Aaron (akehrer) (2015-01-05). "Nim Syntax". GitHub. Retrieved 2015-01-05.
  13. 1 2 3 "Nim Manual". Nim-lang.org. Retrieved 2014-07-20.
  14. "Strangeloop Nim presentation". Archived from the original on 2014-07-13. Retrieved 2015-04-30.
  15. "Nim's Memory Management". nim-lang.org. Retrieved 2023-08-17.
  16. Binstock, Andrew (2014-01-07). "The Rise And Fall of Languages in 2013". Dr. Dobb's Journal . Retrieved 2018-10-08.
  17. Nim Compiler User Guide
  18. 1 2 Sieka, Jacek (2020-07-18), arnetheduck/nlvm , retrieved 2020-07-21
  19. "Nim Releases". Nim Project. Retrieved 2020-01-26.
  20. 1 2 3 4 Picheta, Dominik (2017). Nim in Action. Manning Publications. ISBN   978-1617293436.
  21. "Nim Pascal Sources". GitHub. Retrieved 2013-04-05.
  22. "News". Nim-lang.org. Archived from the original on 2016-06-26. Retrieved 2016-06-11.
  23. "Contributors". GitHub. Retrieved 2013-04-05.
  24. Picheta, Dominik (2014-12-29). "Version 0.10.2 released". Nim-lang.org. Retrieved 2018-10-17.
  25. "Nim v2.0 released". Nim Programming Language. Retrieved 2023-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 , retrieved 2023-10-15
  28. "Nim Manual: Method call syntax" . Retrieved 2018-10-12.
  29. "Nim Manual: Identifier Equality". nim-lang.org. Retrieved 2023-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. Retrieved 2018-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. Retrieved 2014-07-20.
  32. Rumpf, Andreas (2018-10-12). "Nim Compiling". GitHub. Retrieved 2018-10-17.
  33. 1 2 3 "Nim Compiler User Guide".
  34. "Nim's Memory Management". nim-lang.org. Retrieved 2023-08-17.
  35. "Introduction to ARC/ORC in Nim". Nim Programming Language. Retrieved 2023-08-17.
  36. "ORC - Vorsprung durch Algorithmen". Nim Programming Language. Retrieved 2023-08-17.
  37. "Nim v2.0 released". Nim Programming Language. Retrieved 2023-08-17.
  38. "Nimble". GitHub. Retrieved 2018-10-12.
  39. "Nim v0.12.0 release". GitHub. Retrieved 2020-11-28.
  40. "c2nim". GitHub. Retrieved 2018-10-12.
  41. "Nim maintenance script". nim-lang.org. Retrieved 2021-11-16.
  42. "nimgrep User's manual". nim-lang.org. Retrieved 2021-11-16.
  43. "Nim IDE Integration Guide". nim-lang.org. Retrieved 2021-11-16.
  44. "niminst User's manual". nim-lang.org. Retrieved 2021-11-16.
  45. "Tools available with Nim". nim-lang.org. 2021-10-19. Archived from the original on 2015-05-09. Retrieved 2022-02-18.
  46. "choosenim". GitHub. Retrieved 2018-10-12.
  47. Glukhov, Yuriy (2021-11-12), nimpy , retrieved 2021-11-16
  48. nimterop/nimterop, nimterop, 2021-11-12, retrieved 2021-11-16
  49. Nim Standard Library
  50. Installation, The Nim programming language, 2021-09-25, retrieved 2021-11-16
  51. StefanSalewski (2021-11-15), High level GTK4 and GTK3 bindings for the Nim programming language , retrieved 2021-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, retrieved 2021-11-16
  55. Arabadzhi, Vladimir (2021-11-15), sdl2_nim 2.0.14.2 , retrieved 2021-11-16
  56. Cairo, The Nim programming language, 2021-10-05, retrieved 2021-11-16
  57. opengl, The Nim programming language, 2021-11-14, retrieved 2021-11-16
  58. Ward (2021-11-15), Winim , retrieved 2021-11-16
  59. "Vulkanim". GitHub. 2022-09-30.
  60. "Nim Standard Library". Nim documentation. Archived from the original on 2015-04-06. Retrieved 2015-04-04.
  61. Lim, Andri (jangko) (2018-10-17). "nimLUA". GitHub. Retrieved 2018-10-17.
  62. "NimJL". GitHub. 2022-08-24.
  63. "Nbindgen". GitHub. 2022-11-17.
  64. "cs2nim". GitHub. 2022-10-10.
  65. Glukhov, Yuriy (2020-07-20), yglukhov/nimpy , retrieved 2020-07-21
  66. "ts2nim". GitHub. 2022-11-21.
  67. "Nim Manual". nim-lang.org. Retrieved 2021-07-10.
  68. "Nim Forum: Update on strict funcs". forum.nim-lang.org. Retrieved 2023-08-17.
  69. "Nim by Example - First Class Functions".
  70. "Nim Experimental Features: Strict Funcs".
  71. "Nim Manual: Func".
  72. "std/sequtils". nim-lang.org. Retrieved 2023-08-17.
  73. "Nim Manual: Object variants". nim-lang.org. Retrieved 2023-08-17.
  74. "src/fusion/matching". nim-lang.github.io. Retrieved 2023-08-17.
  75. "Nim Tutorial (Part II): Object Oriented Programming". nim-lang.org. Retrieved 2023-08-17.
  76. 1 2 3 4 "Nim by Example - Object Oriented Programming". nim-by-example.github.io. Retrieved 2023-08-17.
  77. "system/exceptions". nim-lang.org. Retrieved 2023-08-17.
  78. "Nim Manual: Type Classes". nim-lang.org. Retrieved 2020-07-21.
  79. "Nim Tutorial (Part III)". nim-lang.org. Retrieved 2023-08-17.
  80. Chronos - An efficient library for asynchronous programming, Status, 2023-08-14, retrieved 2023-08-17
  81. "Nim Forum". nim-lang.org. Retrieved 2015-05-04.
  82. "Primary source code repository and bug tracker". GitHub. Retrieved 2015-05-04.
  83. "Community". Nim Programming Language. Retrieved 2023-08-17.
  84. "Nim Online Conference 2020". Nim. Retrieved 2020-11-28.
  85. "NimConf 2020". Nim. Retrieved 2023-08-17.
  86. "NimConf 2020 Playlist". YouTube. Retrieved 2020-11-28.
  87. "NimConf 2021". NimConf 2021. Retrieved 2023-08-17.
  88. "Nim at OSCON 2015". O'Reilly Open Source Convention (OSCON). O'Reilly Media. 2015-07-20. Archived from the original on 2015-10-06. Retrieved 2018-10-17.
  89. Rumpf, Andreas; Swartz, Jason; Harrison, Matt. "Essential Languages: Nim, Scala, Python". O’Reilly. O'Reilly Media. Retrieved 2018-10-17.
  90. Rumpf, Andreas (2015-10-26). OSCON 2015 – Nim: An Overview. YouTube (Video). Retrieved 2018-10-12.
  91. "Events". fosdem.org. Retrieved 2020-02-17.
  92. "Nim Devroom at FOSDEM 2022 - Call for Participation". Nim Programming Language. Retrieved 2023-08-17.
  93. "Nim Programming Language devroom". archive.fosdem.org. Retrieved 2023-08-17.