Nim (旧称Nimrod) とは命令型、マルチパラダイム、コンパイル言語という特徴を持つプログラミング言語であり、アンドレアス・ランプフにより設計・開発された。Nimは「効率的で表現豊かで優雅」であるように設計されている。メタプログラミング、関数型プログラミング、メッセージパッシング、手続き型プログラミング、オブジェクト指向プログラミングをサポートしており、 コンパイル時のコード生成、代数的データ型、C言語のForeign function interface (FFI)、JavaScriptへのコンパイルなどの機能を提供している。Pythonのようなシンプルな構文で書かれるが、C言語並みの高いパフォーマンスを有している。Nimは様々な用途に使用可能なシステムプログラミング言語であるが、Nimのように比較的新しい(C/C++以降に発表された)言語としては他にもRust、Go、D言語などの言語がある。

## 概要

Nimはシンプルな構文による静的型付け言語である。構文マクロや項書き換えマクロなどのコンパイル時のメタプログラミング機能をサポートしている。項書き換えマクロは例えば`Bignum`や`Matrix`などのデータ構造の効率的ライブラリ実装を可能にしており、`Bignum`や`Matrix`などがあたかも元々の言語機能に組み込まれていたかのような効率的な実装を可能にする。イテレータもサポートしており、このイテレータはNimの中で第一級オブジェクトとして用いることができ、これら機能は関数プログラミングを可能にする。オブジェクト指向プログラミングは継承と多重ディスパッチによってサポートされている。関数はジェネリックになりうるし、オーバーロードも可能である。また`Type`クラスがサポートされており、これはジェネリクスを促進するものである。演算子オーバーロードもサポートされている。Nimは循環参照検出つきの遅延参照カウントに基づくガベージコレクタを搭載している。アンドリュー・ビンストックはNimに関して「(Nimは)PascalおよびPythonにまたがる非常に独創的なデザインを提供し、CやJavaScriptのコードにコンパイルすることができる」と述べた。

## 歴史

Nimの開発は2005年にアンドレアス・ランプフによって始まった。NimのコンパイラはPascalによって書かれていた。2008年にはNimで書かれたコンパイラがリリースされた。Nimのコンパイラはオープンソースであり、アンドレアス・ランプフに加えてボランティアのグループが開発を行っている。

## 言語設計

### Nimに影響を与えた言語

- Modula-3: traced pointer vs untraced pointer.
- Delphi: 型安全な列挙型 (set of char).
- Ada: 部分範囲型、特殊型、safe variant / case object.
- C++: Excessive overloading、ジェネリックプログラミング
- Python: インデントに基づくシンタックス。
- Lisp: マクロ・システム、抽象構文木の採用、同図像性
- Oberon: The export marker.
- C#: async/await, lambda macro.
- Go: Defer.

### コンパイラ

Nimのコンパイラは最適化されたCのコードを吐くことができ、Cのコンパイラなどの外部コンパイラに従ったコンパイルを選択することもできる(ClangやGNU Compiler Collectionなどの多くのコンパイラがサポートされており、これらコンパイラの最適化や移植能力を利用することができる)。Nimのコンパイラは加えてC++とObjective-Cのコードを吐くことができ、これらの言語で書かれたアプリケーションプログラミングインタフェース(API)を備えた簡易なインターフェイスを提供する。この機能によってNimによるiOSやAndroidのアプリケーションの開発も可能である。

### パッケージシステム

Nimble はNimによってNimモジュールをパッケージするのに用いられているパッケージマネージャーである。これは構成にNimScriptを用いている。NimbleはGitリポジトリ上でパッケージの主要ソースとして働く。パッケージのリストはJSONファイルに保存され、nim-lang/packages repositoryから自由にアクセス可能である。このJSONファイルはNimbleに要求されたGit URLを与え、パッケージをクローンし、インストールする。

### ツール

#### Nimble

NimbleはNimモジュールのパッケージに使われているパッケージマネージャである。Nimbleの構成にはNimScriptが使われている。Nimbleのパッケージは主にGitで管理されており、NimbleはGitリポジトリ上で動作する。NimbleのパッケージのリストはJSONファイルに保管されており、nim-lang/packagesリポジトリで自由にアクセス可能である。このJSONファイルはNimbleにGit URLを提供し、そのURLからパッケージがクローンされインストールされる。

#### c2nim

c2nimはAnsi CのコードからNimのコードに変換するときに新たなBindingを生成するのに寄与する。出力は人間に読むことが可能なNimのコードになり、これにより変換後に人の手での改善・改良が可能になる。

### ライブラリ

NimのプログラムはC言語で使われているものであれば、どんなライブラリでも使用することが可能である。GTK2、SDL2、Cairo、OpenGL、WinAPI、zlib、libzip、OpenSSL、cURLなど多くの言語に言語バインディング (Language binding) が存在する。NimはPostgreSQL、MySQL、SQLiteのデータベースを使用することができる。NimはLuaインタープリタおよびPythonインタープリタとインターフェースをとることができる。

## コードの例

以下のコードサンプルはNim 0.13.0.のシンタックスで有効であり、バージョンが新しくなるにつれて記法が変わる可能性がある。

### Hello world

NimによるHello worldのプログラム:

### Stringをひっくり返す

Nimの機能を知るためのシンプルな例。

もっともエキゾチックな機能は暗黙的な`result`変数である。すなわち、returnの型がvoidではないNimのすべてのプロシージャは暗黙的なresult変数を持っており、result変数は返される(returnされる)値を保持している。Forループでは、`countdown`という呼び出しが見られ、このcountdownはイテレータである。もしFor loopに際して型が定義され、またイテレータが省略されればNimのコンパイラは`items`イテレータの使用を試みる。

### メタプログラミング

これはNimのテンプレート機能を使ったメタプログラミングの例である。

`genType`はコンパイル時に呼び出され、`Test`型が作成される。

### Cの関数をラップする

次のプログラムは既存のCのコードがNimで直接使うことができることを示す例である。

この例では有名なCの関数`printf`がインポートされ使用されている。

## コミュニティ

NimはGitHubおよびフォーラムによって主催されているバグのトラッキングをするコミュニティがある。 O'Reilly Open Source Convention (OSCON)でのプレゼンテーションが2015年に行われた。 O'Reilly Community: Essential Languages: Nim, Scala, Python.