Content deleted Content added
No edit summary |
|||
(698 intermediate revisions by more than 100 users not shown) | |||
Line 1:
{{Short description|Programming language}}
{{use dmy dates|date=July 2022|cs1-dates=y}}
{{Infobox programming language
| name
| logo = Nim logo.svg
| logo caption = The Nim crown logo
| screenshot = <!-- Filename only -->
| screenshot caption =
| paradigms = [[Multi-paradigm programming language|Multi-paradigm]]: [[Compiled language|compiled]], [[Concurrent programming|concurrent]], [[Procedural programming|procedural]], [[Imperative programming|imperative]], [[Functional programming|functional]], [[Object-oriented programming|object-oriented]], [[Metaprogramming|meta]]
| designer = Andreas Rumpf<!-- Do not WP:LINK to late German classical archaeologist. -->
| developer = Nim Lang Team<ref>{{cite web |url=https://github.com/nim-lang/Nim/graphs/contributors |title=Contributors to nim-lang/Nim |website=[[GitHub]] |access-date=23 March 2022}}</ref>
| released = {{Start date and age|2008}}
| latest release version = {{wikidata|property|reference|edit|P348}}
| latest release date = {{start date and age|{{wikidata|qualifier|P348|P577}}}}
| typing = [[Static typing|Static]],<ref name="nimbyex">{{cite web |url=https://nim-by-example.github.io/ |title=Nim by example |website=[[GitHub]] |access-date=2014-07-20}}</ref> [[Strong and weak typing|strong]],<ref name="nimrodbg">{{cite conference |url=https://ibob.github.io/slides/nimrodbg/#/ |language=bg |title=Метапрограмиране с Nimrod |last1=Караджов |first1=Захари |last2=Станимиров |first2=Борислав |year=2014 |conference=VarnaConf |conference-url=http://varnaconf.com/ |access-date=2014-07-27}}</ref> [[Type inference|inferred]], [[Structural type system|structural]]
| scope = [[Scope (computer science)|Lexical]]
| programming language = [[Pascal (programming language)|Pascal]] (2005–2008)<br/>Nim (2008–present, self-hosted)
| dialects =
| influenced by = [[Ada (programming language)|Ada]], [[Modula-3]], [[Lisp (programming language)|Lisp]], [[C++]], [[Object Pascal]], [[Python (programming language)|Python]], [[Oberon (programming language)|Oberon]], [[Rust (programming language)|Rust]], [[ParaSail (programming language)|ParaSail]]<ref name = "parasail">{{cite web |url=https://nim-lang.org/araq/destructors.html |title=Nim without GC |first=Andreas |last=Rumpf |website=Araq's Musings |date=2017-10-19 |access-date=2020-09-01}}</ref>
| platform = [[IA-32]], [[x86-64]], [[ARM architecture|ARM]], [[Aarch64]], [[RISC-V]], [[PowerPC]] ...<ref>{{Cite web |url=https://nim-lang.org/docs/packaging.html |title=Packaging Nim |access-date=23 March 2022}}</ref>
| operating system = [[Cross-platform software|Cross-platform]]<ref>{{Cite web |url=https://nim-lang.org/install.html |title=Install Nim |access-date=2018-10-12}}</ref>
| license = {{wikidata|property|reference|edit|P275}}
| website = {{URL|nim-lang.org}}
| file ext = .nim, .nims, .nimble
}}
'''Nim'''
== Description ==
Nim is statically typed.<ref name="Nim Syntax">{{cite web |url=https://akehrer.github.io/posts/getting-started-with-nim |title=Nim Syntax |last=Kehrer |first=Aaron (akehrer) |website=GitHub |date=5 January 2015 |access-date=2015-01-05}}</ref> It supports compile-time [[metaprogramming]] features such as syntactic macros and [[Macro (computer science)#Syntactic macros|term rewriting macros]].<ref name="manual">{{cite web |url=https://nim-lang.org/docs/manual.html#term-rewriting-macros |title=Nim Manual |website=Nim-lang.org |access-date=2014-07-20}}</ref> Term rewriting macros enable [[Library (computing)|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.<ref name="strangeloop">{{cite web |url=https://thestrangeloop.com/sessions/nimrod-a-new-approach-to-meta-programming |archive-url=https://web.archive.org/web/20140713011227/https://thestrangeloop.com/sessions/nimrod-a-new-approach-to-meta-programming |url-status=dead |archive-date=2014-07-13 |title=Strangeloop Nim presentation |access-date=2015-04-30}}</ref> Iterators are supported and can be used as first class entities,<ref name="manual" /> as can functions, allowing for the use of [[functional programming]] methods. [[Object-oriented programming]] is supported by [[Inheritance (object-oriented programming)|inheritance]] and [[multiple dispatch]]. Functions can be generic and overloaded, and [[Generic programming|generics]] are further enhanced by Nim's support for [[type class]]es. [[Operator overloading]] is also supported.<ref name="manual" /> Nim includes multiple tunable memory management strategies, including [[Tracing garbage collection|tracing]] [[Garbage collection (computer science)|garbage collection]], [[reference counting]], and [[Manual memory management|fully manual systems]], with the default being deterministic [[reference counting]] with optimizations via [[move semantics]] and [[Reference counting#Dealing with reference cycles|cycle collection]] via trial deletion.<ref>{{Cite web |title=Nim's Memory Management |url=https://nim-lang.org/docs/mm.html |access-date=2023-08-17 |website=nim-lang.org}}</ref>{{blockquote|text=[Nim] ... presents a most original design that straddles [[Pascal (programming language)|Pascal]] and [[Python (programming language)|Python]] and compiles to C code or JavaScript.<ref>{{cite web|last=Binstock|first=Andrew|date=2014-01-07|title=The Rise And Fall of Languages in 2013|url=http://www.drdobbs.com/jvm/the-rise-and-fall-of-languages-in-2013/240165192|access-date=2018-10-08|website=[[Dr. Dobb's Journal]]}}</ref>
|author=Andrew Binstock, editor-in-chief of [[Dr. Dobb's Journal]], 2014
}}
{{As of|2023|8}}, Nim compiles to C, C++, JavaScript, Objective-C,<ref>[https://nim-lang.org/docs/nimc.html Nim Compiler User Guide]</ref> and LLVM.<ref name=":1" />
== History ==
{| class="wikitable floatright" style="text-align:center; font-size: 85%;"
|-
! Branch
! Version
! Release date<ref>{{cite web |url=https://github.com/nim-lang/Nim/releases |title=Nim Releases |publisher=Nim Project |access-date=2020-01-26}}</ref>
|-
| rowspan="11" | 0.x
| {{Version | o | 0.10.2}}
| 2014-12-29
|-
| {{Version | o | 0.11.2}}
| 2015-05-04
|-
| {{Version | o | 0.12.0}}
| 2015-10-27
|-
| {{Version | o | 0.13.0}}
| 2016-01-18
|-
| {{Version | o | 0.14.2}}
| 2016-06-09
|-
| {{Version | o | 0.15.2}}
| 2016-10-23
|-
| {{Version | o | 0.16.0}}
| 2017-01-08
|-
| {{Version | o | 0.17.2}}
| 2017-09-07
|-
| {{Version | o | 0.18.0}}
| 2018-03-01
|-
| {{Version | o | 0.19.6}}
| 2019-05-13
|-
| {{Version | o | 0.20.2}}
| 2019-06-17
|-
| rowspan="2" | 1.0
| {{Version | o | 1.0.0}}
| 2019-09-23
|-
| {{Version | o | 1.0.10}}
| 2020-10-27
|-
| rowspan="2" | 1.2
| {{Version | o | 1.2.0}}
| 2020-04-03
|-
| {{Version | o | 1.2.18}}
| 2022-02-09
|-
| rowspan="2" | 1.4
| {{Version | o | 1.4.0}}
| 2020-10-16
|-
| {{Version | o | 1.4.8}}
| 2021-05-25
|-
| rowspan="2" | 1.6
| {{Version | o | 1.6.0}}
| 2021-10-19
|-
| {{Version | o | 1.6.20}}
| 2024-04-16
|-
| rowspan="2" | 2.0
| {{Version | o | 2.0.0}}
| 2023-08-01
|-
| {{Version | co | 2.0.16}}
| 2025-04-22
|-
| rowspan="2" | 2.2
| {{Version | o | 2.2.0}}
| 2024-10-02
|-
| {{Version | c | 2.2.4}}
| 2025-04-22
|-
| colspan="3" | {{Version | l | show=111100}}
|-
| colspan="3" | <small>For each 0.x branch, only the latest point release is listed. <br/>For later branches, the first and the latest point release is listed. </small>
|}
Andreas Rumpf is the designer and original implementer of Nim. He received a diploma in computer science from the [[University of Kaiserslautern-Landau]], [[Germany]]. His research interests include hard realtime systems, embedded systems, compiler construction and artificial intelligence.<ref>{{Cite book |last=Andreas Rumpf |title=Mastering Nim: A complete guide to the programming language}}</ref>
Nim's original website design by Dominik Picheta and Hugo Locurcio. Joseph Wecker created the Nim logo.
Nim's initial development was started in 2005 by Andreas Rumpf. It was originally named Nimrod when the project was made public in 2008.<ref name="NimAction">{{Cite book |last=Picheta |first=Dominik |year=2017 |title=Nim in Action |publisher=Manning Publications |isbn=978-1617293436}}</ref>{{rp|4–11}}<!-- Section 1.1: What is Nim? -->
The first version of the Nim [[compiler]] was written in [[Pascal (programming language)|Pascal]] using the [[Free Pascal]] compiler.<ref name="pas-sources">{{cite web |url=https://github.com/Araq/Nim/tree/ea1f1ec6d4d6c776eb0f81c2bebdd4cb4c817ebe/nim |title=Nim Pascal Sources |website=GitHub |access-date=2013-04-05}}</ref> In 2008, a version of the compiler written in Nim was released.<ref name="news">{{cite web |url=http://nim-lang.org:80/news.html |title=News |website=Nim-lang.org |access-date=2016-06-11 |url-status=live |archive-url=https://web.archive.org/web/20160626002904/http://nim-lang.org/news.html |archive-date=2016-06-26}}</ref> The compiler is [[free and open-source software]], and is being developed by a community of volunteers working with Andreas Rumpf.<ref name="contributors">{{cite web |url=https://github.com/Araq/Nim/contributors |title=Contributors |website=GitHub |access-date=2013-04-05}}</ref> The language was officially renamed from ''Nimrod'' to ''Nim'' with the release of version 0.10.2 in December 2014.<ref>{{cite web |url=https://nim-lang.org/blog/2014/12/29/version-0102-released.html |title=Version 0.10.2 released |date=2014-12-29 |first=Dominik |last=Picheta |website=Nim-lang.org |access-date=2018-10-17}}</ref> On September 23, 2019, version 1.0 of Nim was released, signifying the maturing of the language and its toolchain. On August 1, 2023, version 2.0 of Nim was released, signifying the completion, stabilization of, and switch to the ARC/ORC memory model.<ref name="Nim v2.0 released">{{Cite web |title=Nim v2.0 released |url=https://nim-lang.org/blog/2023/08/01/nim-v20-released.html |access-date=2023-08-17 |website=Nim Programming Language |language=en}}</ref>
== Language design ==
=== Syntax ===
The syntax of Nim resembles that of [[Python (programming language)|Python]].<ref name="Yegulalp">{{cite web |url=https://www.infoworld.com/article/3157745/application-development/nim-language-draws-from-best-of-python-rust-go-and-lisp.html |title=Nim language draws from best of Python, Rust, Go, and Lisp |first=Serdar |last=Yegulalp |date=2017-01-16 |website=InfoWorld}}</ref> Code blocks and nesting statements are identified through use of [[Whitespace character|whitespace]], according to the [[Off-side rule|offside-rule]]. Many [[Reserved word|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 (computer science)|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:
* <code>openarray</code> {{En dash}} Represents arrays of different sizes, sequences, and strings
* <code>SomeSignedInt</code> {{En dash}} Represents all the signed integer types
* <code>SomeInteger</code> {{En dash}} Represents all the Integer types, signed or not
* <code>SomeOrdinal</code> {{En dash}} Represents all the basic countable and ordered types, except of non integer number
This code sample demonstrates the use of typeclasses in Nim:
<syntaxhighlight lang="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
</syntaxhighlight>
<syntaxhighlight lang="nim">
# Let's write another function that takes any ordinal type, and returns
# the double of the input in its original type, if it is a number;
# or returns the input itself otherwise.
# We use a generic Type(T), and precise that it can only be an Ordinal
func twiceIfIsNumber[T: SomeOrdinal](i: 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
</syntaxhighlight>
{{codett|lang=nim|echo twiceIfIsNumber(67) # Passes an int to the function}}
echo twiceIfIsNumber{{codett|lang=nim|(67u8) # Passes an uint8}}
{{codett|lang=nim|echo twiceIfIsNumber(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 (programming language)|Python]] flexibility, and powerful [[Lisp (programming language)|Lisp]] macro system.<ref>{{Citation |title=Interview with Nim language creator Andreas Rumpf | date=9 March 2020 |url=https://www.youtube.com/watch?v=-9SGIB946lw |access-date=2023-10-15 |language=en}}</ref>
Nim was influenced by specific characteristics of existing languages, including the following:
*[[Modula-3]]: [[Modula-3#Dynamic allocation|traced vs untraced]] pointers
*[[Object Pascal]]: type safe bit sets (''set of char''), case statement syntax, various type names and filenames in the standard library
*[[Ada (programming language)|Ada]]: subrange types, distinct type, safe variants – case objects
*[[C++]]: [[operator overloading]], [[generic programming]]
*[[Python (programming language)|Python]]: [[Off-side rule]]
*[[Lisp (programming language)|Lisp]]: [[Metaprogramming|Macro system]], [[Abstract syntax tree|AST]] manipulation, [[homoiconicity]]
*[[Oberon (programming language)|Oberon]]: export marker
*[[C Sharp (programming language)|C#]]: [[async/await]], lambda macros
*[[ParaSail (programming language)|ParaSail]]: pointer-free programming<ref name="parasail"/>
=== Uniform function call syntax ===
Nim supports [[uniform function call syntax]] (UFCS)<ref>{{Cite web |url=http://nim-lang.org/docs/manual.html#procedures-method-call-syntax |title=Nim Manual: Method call syntax |access-date=2018-10-12}}</ref> and identifier equality, which provides a large degree of flexibility in use.
For example, each of these lines print [["Hello, World!" program|"hello world"]], just with different syntax:
<syntaxhighlight lang="nim">
echo "hello world"
echo("hello world")
"hello world".echo()
"hello world".echo
echo("hello", " world")
"hello".echo(" world")
"hello".echo " world"
</syntaxhighlight>
=== Identifier equality ===
Nim is almost fully style-insensitive; two [[identifier]]s are considered equal if they only differ by capitalization and underscores, as long as the first characters are identical. This is to enable a mixture of styles across libraries: one user can write a library using snake_case as a convention, and it can be used by a different user in a camelCase style without issue.<ref>{{Cite web |title=Nim Manual: Identifier Equality |url=https://nim-lang.org/docs/manual.html#lexical-analysis-identifier-equality |access-date=2023-08-17 |website=nim-lang.org}}</ref><syntaxhighlight lang="nim">
const useHttps = true
assert useHttps == useHttps
assert useHTTPS == useHttps
assert use_https == useHttps
</syntaxhighlight>
=== Stropping ===
The [[Stropping (syntax)|stropping]] feature allows the use of any name for variables or functions, even when the names are [[reserved word]]s for keywords. An example of stropping is the ability to define a variable named <code>if</code>, without clashing with the keyword <code>if</code>. Nim's implementation of this is achieved via backticks, allowing any reserved word to be used as an identifier.<ref>{{cite web |url=https://github.com/nim-lang/Nim/wiki/Tips-and-tricks |title=Tips and tricks |last1=Picheta |first1=Dominik (dom96) |last2=Wetherfordshire |first2=Billingsly (fowlmouth) |last3=Felsing |first3=Dennis (def-) |last4=Raaf |first4=Hans (oderwat) |last5=Dunn |first5=Christopher (cdunn2001) |author6=wizzardx |date=2017-10-25 |website=GitHub |access-date=2018-10-17}}</ref>
<syntaxhighlight lang="nim">
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`
</syntaxhighlight>
== Compiler ==
The Nim compiler emits fast, optimized [[C (programming language)|C]] code by default. It defers compiling-to-object code to an external C compiler<ref name="infoq">{{cite AV media |last=Rumpf |first=Andreas |url=http://www.infoq.com/presentations/nimrod |title=Nimrod: A New Approach to Metaprogramming |website=InfoQ |time=2:23 |date=2014-01-15 |access-date=2014-07-20}}</ref> 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 ([[API]]s) written in those languages;<ref name="drdobbs"/> developers can simply write in Nim, then compile to any supported language. This also allows writing applications for [[iOS]] and [[Android (operating system)|Android]]. There is also an unofficial [[LLVM]] backend, allowing use of the Nim compiler in a stand-alone way.<ref name=":1">{{Citation|last=Sieka|first=Jacek|title=arnetheduck/nlvm|date=2020-07-18|url=https://github.com/arnetheduck/nlvm|access-date=2020-07-21}}</ref>
The Nim compiler is [[Self-hosting (compilers)|self-hosting]], meaning it is written in the Nim language.<ref>{{Cite web |url=https://github.com/nim-lang/Nim#compiling |title=Nim Compiling |last=Rumpf |first=Andreas |date=2018-10-12 |website=GitHub |access-date=2018-10-17}}</ref> 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|date=October 2023}}
=== Compiler options ===
By default, the Nim compiler creates a ''debug'' build.<ref name="build-mode">{{Cite web|url=https://nim-lang.org/docs/nimc.html#compiler-usage-configuration-files|title = Nim Compiler User Guide}}</ref>
With the option <code>-d:release</code> a ''release'' build can be created, which is optimized for speed and contains fewer runtime checks.<ref name="build-mode" />
With the option <code>-d:danger</code> all runtime checks can be disabled, if maximum speed is desired.<ref name="build-mode" />
=== Memory management ===
Nim supports multiple memory management strategies, including the following:<ref>{{Cite web |title=Nim's Memory Management |url=https://nim-lang.org/docs/mm.html |access-date=2024-07-28 |website=nim-lang.org}}</ref>
* <code>--mm:arc</code> – Automatic [[reference counting]] (ARC) with [[move semantics]] optimizations, offers a shared heap. It offers fully deterministic performance for hard realtime systems.<ref>{{Cite web |title=Introduction to ARC/ORC in Nim |url=https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc-in-nim.html |access-date=2023-08-17 |website=Nim Programming Language |language=en}}</ref> Reference cycles may cause memory leaks: these may be dealt with by manually annotating <code>{.acyclic.}</code> pragmas or by using <code>--mm:orc</code>.
* <code>--mm:orc</code> – Same as <code>--mm:arc</code> but adds a cycle collector (the "O") based on "trial deletion".<ref>{{Cite web |title=ORC - Vorsprung durch Algorithmen |url=https://nim-lang.org/blog/2020/12/08/introducing-orc.html |access-date=2023-08-17 |website=Nim Programming Language |language=en}}</ref> The cycle collector only analyzes types if they are potentially cyclic.
* <code>--mm:refc</code> – Standard deferred [[reference counting]] based [[Garbage collection (computer science)|garbage collector]] with a simple mark-and-sweep backup GC in order to collect cycles. Heaps are thread-local.
* <code>--mm:markAndSweep</code> – Simple [[Mark and sweep|mark-and-sweep]] based [[Garbage collection (computer science)|garbage collector]]. Heaps are thread-local.
* <code>--mm:boehm</code> – [[Boehm garbage collector|Boehm]] based [[Garbage collection (computer science)|garbage collector]], it offers a shared heap.
* <code>--mm:go</code> – [[Go (programming language)|Go]]'s [[Garbage collection (computer science)|garbage collector]], useful for interoperability with [[Go (programming language)|Go]]. Offers a shared heap.
* <code>--mm:none</code> – No memory management strategy nor a [[Garbage collection (computer science)|garbage collector]]. Allocated memory is simply never freed, unless manually freed by the developer's code.
As of Nim 2.0, ORC is the default GC.<ref name="Nim v2.0 released"/>
== 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.<ref>{{Cite web |url=https://github.com/nim-lang/nimble |title=Nimble |website=GitHub |access-date=2018-10-12}}</ref> 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.<ref>{{Cite web |url=https://github.com/nim-lang/Nim/commit/49d810f3410c19803f2d6fbfb3feb03e1fc13fee |title=Nim v0.12.0 release |website=GitHub |access-date=November 28, 2020}}</ref>
Nimble packages are defined by <code>.nimble</code> files, which contain information about the package version, author, license, description, dependencies, and more.<ref name="NimAction"/>{{rp|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:
<code>nimble -v</code>.
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.<ref name="NimAction"/>{{rp|130–131}}
==== c2nim ====
c2nim is a [[source-to-source compiler]] (transcompiler or transpiler) meant to be used on [[ANSI C|C]]/[[C++]] headers to help generate new Nim bindings.<ref>{{Cite web |url=https://github.com/nim-lang/c2nim |title=c2nim |website=GitHub |access-date=2018-10-12}}</ref> 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.<ref>{{Cite web|title=Nim maintenance script|url=https://nim-lang.org/docs/koch.html|access-date=2021-11-16|website=nim-lang.org}}</ref>
==== 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.<ref>{{Cite web|title=nimgrep User's manual|url=https://nim-lang.org/docs/nimgrep.html|access-date=2021-11-16|website=nim-lang.org}}</ref>
==== nimsuggest ====
nimsuggest is a tool that helps any source code editor query a <code>.nim</code> source file to obtain useful information like definition of symbols or suggestions for completions.<ref>{{Cite web|title=Nim IDE Integration Guide|url=https://nim-lang.org/docs/nimsuggest.html|access-date=2021-11-16|website=nim-lang.org}}</ref>
==== niminst ====
niminst is a tool to generate an installer for a Nim program.<ref>{{Cite web|title=niminst User's manual|url=https://nim-lang.org/docs/niminst.html|access-date=2021-11-16|website=nim-lang.org}}</ref>
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.<ref>{{cite web|date=2021-10-19|title=Tools available with Nim|url=https://nim-lang.org/docs/tools.html|url-status=live|website=nim-lang.org |archive-url=https://web.archive.org/web/20150509003939/https://nim-lang.org/docs/tools.html |archive-date=2015-05-09 |access-date=2022-02-18}}</ref>
==== Testament ====
[https://nim-lang.github.io/Nim/testament.html 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 ====
[https://github.com/dom96/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.<ref>{{cite web |url=https://github.com/dom96/choosenim |title=choosenim |website=GitHub |access-date=2018-10-12}}</ref>
==== nimpy ====
[https://github.com/yglukhov/nimpy nimpy] is a library that enables convenient Python integration in Nim programs.<ref>{{Citation|last=Glukhov|first=Yuriy|title=nimpy|date=2021-11-12|url=https://github.com/yglukhov/nimpy|access-date=2021-11-16}}</ref>
==== pixie ====
[https://github.com/treeform/pixie pixie] is a feature-rich 2D graphics library, similar to [[Cairo (graphics)|Cairo]] or the [[Skia Graphics Engine|Skia]]. It uses [[Single instruction, multiple data|SIMD]] acceleration to speed-up image manipulation drastically. It supports many image formats, blending, masking, blurring, and can be combined with the [https://github.com/treeform/boxy boxy] library to do hardware accelerated rendering.
==== nimterop ====
[https://github.com/nimterop/nimterop nimterop] is a tool focused on automating the creation of C/C++ wrappers needed for Nim's foreign function interface.<ref>{{Citation|title=nimterop/nimterop|date=2021-11-12|url=https://github.com/nimterop/nimterop|publisher=nimterop|access-date=2021-11-16}}</ref>
== 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:<ref>[https://nim-lang.org/docs/lib.html Nim Standard Library]</ref>
* 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 (computing)|library]] which can be used in a C, C++, or JavaScript program. [[Language binding]]s exist for many libraries, including [[GTK]],<ref>{{Citation|title=Installation|date=2021-09-25|url=https://github.com/nim-lang/gtk2|publisher=The Nim programming language|access-date=2021-11-16}}</ref><ref>{{Citation|last=StefanSalewski|title=High level GTK4 and GTK3 bindings for the Nim programming language|date=2021-11-15|url=https://github.com/StefanSalewski/gintro|access-date=2021-11-16}}</ref> [[Qt (software)|Qt]] QML,<ref>{{cite web |url=https://github.com/status-im/NimQml |title=NimQml |website=GitHub|date=10 November 2022 }}</ref> [[wxWidgets]],<ref>{{cite web |url=https://github.com/PMunch/wxnim |title=WxNim |website=GitHub|date=29 November 2022 }}</ref> [[Simple DirectMedia Layer|SDL 2]],<ref>{{Citation|title=SDL2 for Nim|date=2021-10-26|url=https://github.com/nim-lang/sdl2|publisher=The Nim programming language|access-date=2021-11-16}}</ref><ref>{{Citation|last=Arabadzhi|first=Vladimir|title=sdl2_nim 2.0.14.2|date=2021-11-15|url=https://github.com/Vladar4/sdl2_nim|access-date=2021-11-16}}</ref> [[Raylib]],<ref>{{cite web |url=https://github.com/planetis-m/naylib |title=naylib |website=GitHub|date=28 July 2024 }}</ref> [[Godot (game engine)|Godot]],<ref>{{cite web |url=https://github.com/godot-nim |title=godot-nim |website=GitHub|date=28 July 2024 }}</ref> [[UE5]],<ref>{{cite web |url=https://github.com/jmgomez/NimForUE |title=NimForUE |website=GitHub|date=28 July 2024 }}</ref> [[Cairo (graphics)|Cairo]],<ref>{{Citation|title=Cairo|date=2021-10-05|url=https://github.com/nim-lang/cairo|publisher=The Nim programming language|access-date=2021-11-16}}</ref> [[OpenGL]],<ref>{{Citation|title=opengl|date=2021-11-14|url=https://github.com/nim-lang/opengl|publisher=The Nim programming language|access-date=2021-11-16}}</ref> [[Vulkan]],<ref>{{cite web |url=https://github.com/nimgl/vulkan |title=vulkan |website=GitHub|date=28 July 2024 }}</ref> [[Windows API|WinAPI]],<ref>{{Citation|last=Ward|title=Winim|date=2021-11-15|url=https://github.com/khchen/winim|access-date=2021-11-16}}</ref> [[zlib]], [[libzip]], [[OpenSSL]] and [[cURL]].<ref name="lib">{{cite web |url=http://nim-lang.org/lib.html |title=Nim Standard Library |website=Nim documentation |access-date=2015-04-04 |url-status=dead |archive-url=https://web.archive.org/web/20150406053933/http://nim-lang.org/lib.html |archive-date=2015-04-06 }}</ref> 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 (programming language)|Lua]],<ref>{{cite web |url=https://github.com/jangko/nimLUA |title=nimLUA |last=Lim |first=Andri (jangko) |date=2018-10-17 |website=GitHub |access-date=2018-10-17}}</ref> [[Julia (programming language)|Julia]],<ref>{{cite web |date=24 August 2022 |title=NimJL |url=https://github.com/Clonkk/nimjl |website=GitHub}}</ref> [[Rust (programming language)|Rust]],<ref>{{cite web |url=https://github.com/arnetheduck/nbindgen |title=Nbindgen |website=GitHub|date=17 November 2022 }}</ref>
[[C Sharp (programming language)|C#]],<ref>{{cite web |url=https://github.com/kobi2187/cs2nim |title=cs2nim |website=GitHub|date=10 October 2022 }}</ref>
and [[Python (programming language)|Python]]<ref>{{Citation|last=Glukhov|first=Yuriy|title=yglukhov/nimpy|date=2020-07-20|url=https://github.com/yglukhov/nimpy|access-date=2020-07-21}}</ref> programming languages or transpile Nim to [[TypeScript]].<ref>{{cite web |date=21 November 2022 |title=ts2nim |url=https://github.com/bung87/ts2nim |website=GitHub}}</ref>
== Examples ==
=== Hello world ===
The [["Hello, World!" program]] in Nim:
<syntaxhighlight lang="nim">
echo("Hello, World!")
# Procedures can be called with no parentheses
echo "Hello, World!"
</syntaxhighlight>
Another version of "Hello World" can be accomplished by calling the <code>write</code> function with the <code>stdout</code> stream:
<syntaxhighlight lang="nim">
stdout.write("Hello, World!\n")
write(stdout, "Hello, World!\n")
</syntaxhighlight>
=== Fibonacci ===
Several implementations of the [[Fibonacci function]], showcasing implicit returns, default parameters, iterators, recursion, and while loops:<syntaxhighlight lang="nim">
proc fib(n: Natural): Natural =
if n < 2:
return n
else:
return fib(n-1) + fib(n-2)
func fib2(n: int, a = 0, b = 1): int =
if n == 0: a else: fib2(n-1, b, a+b)
iterator fib3: int =
var a = 0
var b = 1
while true:
yield a
swap a, b
b += a
</syntaxhighlight>
=== Factorial ===
Program to calculate the [[factorial]] of a positive integer using the iterative approach, showcasing try/catch error handling and for loops:<syntaxhighlight lang="nim">
import std/strutils
var n = 0
try:
stdout.write "Input positive integer number: "
n = stdin.readline.parseInt
except ValueError:
raise newException(ValueError, "You must enter a positive number")
var fact = 1
for i in 2..n:
fact = fact * i
echo fact
</syntaxhighlight>Using the module math from Nim's standard library:<syntaxhighlight lang="nim">
import std/math
echo fac(x)
</syntaxhighlight>
=== Reversing a string ===
A simple demonstration showing the implicit result variable and the use of iterators.
<syntaxhighlight lang="
proc reverse(s: string): string =
for i in countdown(s.high, 0):
result.add s[i]
echo "Reversed: ", reverse(str1)
</syntaxhighlight>
One of Nim's more exotic features is the implicit <code>result</code> 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 <code>countdown</code> which is an iterator. If an iterator is omitted, the compiler will attempt to use an <code>items</code> iterator, if one is defined for the type specified.
=== Graphical user interface ===
Using [[GTK|GTK 3]] with GObject introspection through the [https://github.com/StefanSalewski/gintro gintro] module:
<syntaxhighlight lang="nim">
import gintro/[gtk, 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()
</syntaxhighlight>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 function]]s and code without [[Side effect (computer science)|side effects]] via the <code>noSideEffect</code> pragma or the <code>func</code> keyword.<ref>{{Cite web|title=Nim Manual|url=https://nim-lang.org/docs/manual.html#procedures-func|access-date=2021-07-10|website=nim-lang.org}}</ref> Nim will perform [[Side effect (computer science)|side effect]] analysis and raise compiling errors for code that does not obey the contract of producing no [[Side effect (computer science)|side effects]] when compiled with the experimental feature <code>strictFuncs</code>, planned to become the default in later versions.<ref>{{Cite web |title=Nim Forum: Update on strict funcs |url=https://forum.nim-lang.org/t/9716 |access-date=2023-08-17 |website=forum.nim-lang.org}}</ref>
Contrary to purely [[functional programming]] languages, Nim is a [[Programming paradigm#Support for multiple paradigms|multi-paradigm]] programming language, so [[functional programming]] restrictions are opt-in on a function-by-function basis.
==== First-class functions ====
Nim supports [[first-class function]]s by allowing functions to be stored in variables or passed anonymously as parameters to be invoked by other functions.<ref>{{Cite web |title=Nim by Example - First Class Functions |url=https://nim-by-example.github.io/procvars/}}</ref> The <code>std/sugar</code> module provides syntactic sugar for anonymous functions in type declarations and instantiation.<syntaxhighlight lang="nim">
import std/[sequtils, sugar]
let powersOfTwo = @[1, 2, 4, 8, 16, 32, 64, 128, 256]
proc filter[T](s: openArray[T], pred: T -> bool): seq[T] =
result = newSeq[T]()
for i in 0 ..< s.len:
if pred(s[i]):
result.add(s[i])
echo powersOfTwo.filter(proc (x: int): bool = x > 32)
# syntactic sugar for the above, provided as a macro from std/sugar
echo powersOfTwo.filter(x => x > 32)
proc greaterThan32(x: int): bool = x > 32
echo powersOfTwo.filter(greaterThan32)
</syntaxhighlight>
==== Side effects ====
Side effects of functions annotated with the <code>noSideEffect</code> 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 <code>var</code> or <code>ref</code> type: this is expected to fail to compile with the currently-experimental <code>strictFuncs</code> in the future.<ref>{{Cite web |title=Nim Experimental Features: Strict Funcs |url=https://nim-lang.org/docs/manual_experimental.html#strict-funcs}}</ref> The <code>func</code> keyword introduces a shortcut for a <code>noSideEffect</code> pragma.<ref>{{Cite web |title=Nim Manual: Func |url=https://nim-lang.org/docs/manual.html#procedures-func}}</ref>
{{pre|1=
{{codett|lang=nim|func binarySearch[T](a: openArray[T]; elem: T): int}}
# is short for...
{{codett|lang=nim|proc binarySearch[T](a: openArray[T]; elem: T): int}} {.noSideEffect.}
{.experimental: "strictFuncs".}
{{codett|lang=nim|type}}
{{codett|lang=nim|1=Node = ref object}}
{{codett|lang=nim|1=le, ri: Node}}
{{codett|lang=nim|1=data: string}}
{{codett|lang=nim|1=func len(n: Node): int =}}
# valid: len does not have side effects
{{codett|lang=nim|1=var it = n}}
{{codett|lang=nim|1=while it != nil:}}
{{codett|lang=nim|1=inc result}}
{{codett|lang=nim|1=it = it.ri}}
{{codett|lang=nim|1=func mut(n: Node) =}}
{{codett|lang=nim|1=let m = n # is the statement that connected the mutation to the parameter}}
{{codett|lang=nim|1=m.data = "yeah" # the mutation is here}}
{{codett|lang=nim|1=# Error: 'mut' can have side effects}}
{{codett|lang=nim|1=# an object reachable from 'n' is potentially mutated}}
}}
==== Function composition ====
[[Uniform function call syntax]] allows the [[Function composition (computer science)|chaining of arbitrary functions]], perhaps best exemplified with the <code>std/sequtils</code> library.<ref>{{Cite web |title=std/sequtils |url=https://nim-lang.org/docs/sequtils.html |access-date=2023-08-17 |website=nim-lang.org}}</ref><syntaxhighlight lang="nim">
import std/[sequtils, sugar]
let numbers = @[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
echo numbers.filter(x => x > 3).deduplicate.foldr(a + b) # 30
</syntaxhighlight>
==== Algebraic data types and pattern matching ====
Nim has support for [[product type]]s via the <code>object</code> type, and for [[sum type]]s via [[Variant type|object variants]]: raw representations of [[tagged union]]s, with an enumerated type tag that must be [[Pattern matching|safely matched upon]] before fields of variants can be accessed.<ref>{{Cite web |title=Nim Manual: Object variants |url=https://nim-lang.org/docs/manual.html#types-object-variants |access-date=2023-08-17 |website=nim-lang.org}}</ref> These types can be [[Algebraic data type|composed algebraically]]. [[Structural pattern matching]] is available, but relegated to macros in various third-party libraries.<ref>{{Cite web |title=src/fusion/matching |url=https://nim-lang.github.io/fusion/src/fusion/matching.html |access-date=2023-08-17 |website=nim-lang.github.io}}</ref><syntaxhighlight lang="nim">
import std/tables
type
Value = uint64
Ident = string
ExprKind = enum
Literal, Variable, Abstraction, Application
Expr = ref object
case kind: ExprKind
of Literal:
litIdent: Value
of Variable:
varIdent: Ident
of Abstraction:
paramAbs: Ident
funcAbs: Expr
of Application:
funcApp, argApp: Expr
func eval(expr: Expr, context: var Table[Ident, Value]): Value =
case expr.kind
of Literal:
return expr.litIdent
of Variable:
return context[expr.varIdent]
of Application:
case expr.funcApp.kind
of Abstraction:
context[expr.funcApp.paramAbs] = expr.argApp.eval(context)
return expr.funcAbs.eval(context)
else:
raise newException(ValueError, "Invalid expression!")
else:
raise newException(ValueError, "Invalid expression!")
</syntaxhighlight>
=== Object-oriented programming ===
Despite being primarily an imperative and functional language, Nim supports various features for enabling object-oriented paradigms.<ref>{{Cite web |title=Nim Tutorial (Part II): Object Oriented Programming |url=https://nim-lang.org/docs/tut2.html#object-oriented-programming |access-date=2023-08-17 |website=nim-lang.org}}</ref><ref name=":0">{{Cite web |title=Nim by Example - Object Oriented Programming |url=https://nim-by-example.github.io/oop/ |access-date=2023-08-17 |website=nim-by-example.github.io}}</ref>
==== Subtyping and inheritance ====
Nim supports limited inheritance by use of <code>ref objects</code> and the <code>of</code> keyword.<ref name=":0" /> To enable inheritance, any initial ("root") object must inherit from <code>RootObj</code>. Inheritance is of limited use within idiomatic Nim code: with the notable exception of Exceptions.<ref>{{Cite web |title=system/exceptions |url=https://nim-lang.org/docs/exceptions.html |access-date=2023-08-17 |website=nim-lang.org}}</ref><syntaxhighlight lang="nim">
type Animal = ref object of RootObj
name: string
age: int
type Dog = ref object of Animal
type Cat = ref object of Animal
var animals: seq[Animal] = @[]
animals.add(Dog(name: "Sparky", age: 10))
animals.add(Cat(name: "Mitten", age: 10))
for a in animals:
assert a of Animal
</syntaxhighlight>Subtyping relations can also be queried with the <code>of</code> keyword.<ref name=":0" />
==== 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.
<syntaxhighlight lang="nim">
type Socket* = ref object
host: int # private, lacks export marker
# getter of host address
proc host*(s: Socket): int = s.host
# setter of host address
proc `host=`*(s: var Socket, value: int) =
s.host = value
var s: Socket
new s
assert s.host == 0 # same as host(s), s.host()
s.host = 34 # same as `host=`(s, 34)
</syntaxhighlight>
==== Dynamic dispatch ====
[[Static dispatch]] is preferred, more performant, and standard even among method-looking routines.<ref name=":0" /> Nonetheless, if dynamic dispatch is so desired, Nim provides the <code>method</code> keyword for enabling [[dynamic dispatch]] on reference types.<syntaxhighlight lang="nim">
import std/strformat
type
Person = ref object of RootObj
name: string
Student = ref object of Person
Teacher = ref object of Person
method introduce(a: Person) =
raise newException(CatchableError, "Method without implementation override")
method introduce(a: Student) =
echo &"I am a student named {a.name}!"
method introduce(a: Teacher) =
echo &"I am a teacher named {a.name}!"
let people: seq[Person] = @[Teacher(name: "Alice"), Student(name: "Bob")]
for person in people:
person.introduce()
</syntaxhighlight>
=== Metaprogramming ===
==== Templates ====
Nim supports simple substitution on the abstract syntax tree via its templates.
<syntaxhighlight lang="
template genType(name, fieldname:
type
name = object
Line 67 ⟶ 608:
echo(x.foo) # 4566
</syntaxhighlight>
The <code>genType</code> is invoked at compile-time and a <code>Test</code> type is created.
==== Generics ====
Nim supports both constrained and unconstrained generic programming.
Generics may be used in procedures, templates and macros. Unconstrained generic identifiers (<code>T</code> 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.
<syntaxhighlight lang="nim">
proc addThese[T](a, b: T): T = a + b
echo addThese(1, 2) # 3 (of int type)
echo addThese(uint8 1, uint8 2) # 3 (of uint8 type)
# we don't want to risk subtracting unsigned numbers!
proc subtractThese[T: SomeSignedInt | float](a, b: T): T = a - b
echo subtractThese(1, 2) # -1 (of int type)
import std/sequtils
# constrained generics can also be directly on the parameters
proc compareThese[T](a, b: string | seq[T]): bool =
for (i, j) in zip(a, b):
if i != j:
return false
</syntaxhighlight>One can further clarify which types the procedure will accept by specifying a type class (in the example above, <code>SomeSignedInt</code>).<ref>{{Cite web |title=Nim Manual: Type Classes |url=https://nim-lang.org/docs/manual.html#generics-type-classes |access-date=2020-07-21 |website=nim-lang.org}}</ref>
==== 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.<ref>{{Cite web |title=Nim Tutorial (Part III) |url=https://nim-lang.org/docs/tut3.html |access-date=2023-08-17 |website=nim-lang.org}}</ref>
Here's a simple example that creates a macro to call code twice:<syntaxhighlight lang="nim">
import std/macros
macro twice(arg: untyped): untyped =
result = quote do:
`arg`
`arg`
twice echo "Hello world!"
</syntaxhighlight>
The <code>twice</code> 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:<syntaxhighlight lang="nim">
echo "Hello world!"
echo "Hello world!"
</syntaxhighlight>
=== 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.<ref name="NimAction" />{{rp|226}}
The following program shows the ease with which external C code can be used directly in Nim.
<syntaxhighlight lang="nim">
proc printf(formatstr: cstring) {.header: "<stdio.h>", varargs.}
printf("%s %d\n", "foo", 5)
</syntaxhighlight>
In this code the <code>printf</code> function is imported into Nim and then used.
Basic example using 'console.log' directly for the [[JavaScript]] compiling target:
<syntaxhighlight lang="nim">
proc log(args: any) {.importjs: "console.log(@)", varargs.}
log(42, "z", true, 3.14)
</syntaxhighlight>
The JavaScript code produced by the Nim compiler can be executed with [[Node.js]] or a web browser.
=== Parallelism ===
{{Expand section|date=June 2019}}
To activate threading support in Nim, a program should be compiled with <code>--threads:on</code> 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.<syntaxhighlight lang="nim">
import std/locks
var
thr: array[0..4, Thread[tuple[a,b: int]]]
L: Lock
proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
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)
</syntaxhighlight>Nim also has a <code>channels</code> module that simplifies passing data between threads.<syntaxhighlight lang="nim">
import std/os
type
CalculationTask = object
id*: int
data*: int
CalculationResult = object
id*: int
result*: int
var task_queue: Channel[CalculationTask]
var result_queue: Channel[CalculationResult]
proc workerFunc() {.thread.} =
result_queue.open()
while true:
var task = task_queue.recv()
result_queue.send(CalculationResult(id: task.id, result: task.data * 2))
var workerThread: Thread[void]
createThread(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())
</syntaxhighlight>
=== Concurrency ===
{{Expand section|date=June 2019}}
Asynchronous IO is supported either via the <code>asyncdispatch</code> module in the standard library or the external <code>chronos</code> library.<ref>{{Citation |title=Chronos - An efficient library for asynchronous programming |date=2023-08-14 |url=https://github.com/status-im/nim-chronos |access-date=2023-08-17 |publisher=Status}}</ref> Both libraries add [[async/await]] syntax via the macro system, without need for special language support. An example of an asynchronous [[Hypertext Transfer Protocol|HTTP]] server:<syntaxhighlight lang="nim">
import std/[asynchttpserver, asyncdispatch]
# chronos could also be alternatively used in place of asyncdispatch,
# with no other changes.
var server = newAsyncHttpServer()
proc cb(req: Request) {.async.} =
await req.respond(Http200, "Hello World")
waitFor server.serve(Port(8080), cb)
</syntaxhighlight>
== Community ==
=== Online ===
Nim has an active community on the self-hosted, self-developed official forum.<ref>{{cite web |url=http://forum.nim-lang.org |title=Nim Forum |publisher=nim-lang.org |access-date=2015-05-04}}</ref> Further, the project uses a Git repository, bug tracker, RFC tracker, and wiki hosted by [[GitHub]], where the community engages with the language.<ref>{{cite web |url=https://github.com/Araq/Nim |title=Primary source code repository and bug tracker |website=GitHub |access-date=2015-05-04}}</ref> There are also official online chat rooms, bridged between [[Internet Relay Chat|IRC]], [[Matrix (protocol)|Matrix]], [[Discord]], [[Gitter]], and [[Telegram (software)|Telegram]].<ref>{{Cite web |title=Community |url=https://nim-lang.org/community.html |access-date=2023-08-17 |website=Nim Programming Language |language=en}}</ref>
=== 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.<ref>{{cite web |url=https://nim-lang.org/blog/2020/05/14/nim-conference.html |title=Nim Online Conference 2020 |website=Nim |access-date=November 28, 2020}}</ref> 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]].<ref>{{cite web |title=NimConf 2020 |url=https://conf.nim-lang.org/2020/ |access-date=August 17, 2023 |website=Nim}}</ref> NimConf 2020 is available as a YouTube playlist.<ref>{{cite web |url=https://www.youtube.com/playlist?list=PLxLdEZg8DRwTIEzUpfaIcBqhsj09mLWHx |title=NimConf 2020 Playlist |website=YouTube |access-date=November 28, 2020}}</ref> NimConf 2021 occurred the following year, was also held digitally, and included talks about [[Video game development|game development]], [[Read–eval–print loop|REPLs]], [[real-time operating system]]s, Nim in the industry, [[Object–relational mapping|object-relational mapping]] (ORM), [[fuzzing]], [[Programming language design|language design]], and [[Graphics library|graphics libraries]].<ref>{{Cite web |title=NimConf 2021 |url=https://conf.nim-lang.org/ |access-date=2023-08-17 |website=NimConf 2021 |language=en}}</ref>
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.<ref>{{cite web |url=http://www.oscon.com/open-source-2015/public/schedule/detail/42497 |title=Nim at OSCON 2015 |date=2015-07-20 |website=[[O'Reilly Open Source Convention]] (OSCON) |publisher=O'Reilly Media |access-date=2018-10-17 |archive-date=2015-10-06 |archive-url=https://web.archive.org/web/20151006182449/http://www.oscon.com/open-source-2015/public/schedule/detail/42497 |url-status=dead }}</ref><ref>{{cite web |title=Essential Languages: Nim, Scala, Python |url=http://www.oreilly.com/pub/e/3420 |last1=Rumpf |first1=Andreas |last2=Swartz |first2=Jason |last3=Harrison |first3=Matt |website=O’Reilly |publisher=O'Reilly Media |access-date=2018-10-17}}</ref><ref>{{cite AV media |last=Rumpf |first=Andreas |date=2015-10-26 |title=OSCON 2015 – Nim: An Overview |medium=Video |language=en |url=https://www.youtube.com/watch?v=4rJEBs_Nnaw |access-date=2018-10-12 |website=YouTube}}</ref> Four speakers represented Nim at [[FOSDEM]] 2020, including the creator of the language, Andreas Rumpf.<ref>{{Cite web|url=https://fosdem.org/2020/schedule/events/|title=Events|website=fosdem.org|language=en|access-date=2020-02-17}}</ref> At FOSDEM 2022, Nim hosted their own developer room virtually due to the [[COVID-19 pandemic]].<ref>{{Cite web |title=Nim Devroom at FOSDEM 2022 - Call for Participation |url=https://nim-lang.org/blog/2021/12/02/fosdem-2022-cfp.html |access-date=2023-08-17 |website=Nim Programming Language |language=en}}</ref> Talks were held on [[Concurrency (computer science)|concurrency]], [[Embedded software|embedded programming]], programming for [[Graphics processing unit|GPUs]], [[Entity component system|entity-component systems]], [[Video game development|game development]], [[rules engine]]s, [[Python (programming language)|Python]] [[Interoperability|interop]], and [[metaprogramming]].<ref>{{Cite web |title=Nim Programming Language devroom |url=https://archive.fosdem.org/2022/schedule/track/nim_programming_language/ |access-date=2023-08-17 |website=archive.fosdem.org |language=en}}</ref>
== See also ==
{{Portal|Computer programming}}
* [[Crystal (programming language)]]
* [[D (programming language)]]
* [[Fat pointer]]
== References ==
{{Reflist|30em}}
== External links ==
* {{Official website}}
* {{GitHub|nim-lang/Nim}}
* [https://stackoverflow.com/questions/tagged/nim-lang Information about Nim] on [[Stack Overflow]]
* [http://ssalewski.de/nimprogramming.html Computer Programming with the Nim Programming Language] A gentle Introduction by Stefan Salewski
{{Programming languages}}
{{JavaScript}}
[[Category:
[[Category:Concurrent programming languages]]
[[Category:
[[Category:Functional languages]]
[[Category:Multi-paradigm programming languages]]
[[Category:Procedural programming languages]]
[[Category:Programming languages
[[Category:Programming languages created in 2008]]
[[Category:Software using the MIT license]]
[[Category:Source-to-source compilers]]
[[Category:Statically typed programming languages]]
[[Category:Systems programming languages]]
|