2019年7月24日水曜日

Nimの紹介 − Python風静的型付言語 〜コンパイラと型推論を添えて〜

勉強の為に転載しました。
http://h-miyako.hatenablog.com/entry/2015/01/13/201846

はじめに

Nim (旧称: Nimrod) というVimに似た名称のPython風構文な静的型付言語があります。 先日Twitterで存在を知り、少し触ってみました *1。 書きやすい上に実行速度がとても速く(単純な処理でgo, rustより早くC並)、非常に気に入ったので簡単にインストール方法などを紹介したいと思います。
  • 注意
    • 筆者はPythonくらいしかよくわからないのでPython (version >= 3.0) 基準です
    • 試した環境はUbuntu 14.04 (64bit)です

Nimの特徴

主に公式ページの記述から、主観で特徴を列挙します。
いい感じです。 特徴だけ眺めるとまるでPython風構文のC++ですね! 競合する言語は、有名ドコロだとC++, Rust, Go, Objective-Cなどでしょうか。
日本語の情報は少ないのですが、旧称のNimrodで検索するとブログ記事を書いてくださっている方もいらっしゃいます。 Nimrod Advent Calendar jp: 2011 : ATNDなどもありました。
参考: Nimが影響を受けた言語(影響の強い順)
Modula-3, Delphi, Ada, C++PythonLisp, Oberon
意外にもPythonは後ろのほうで、上位はPascal系です。 外面はPascal感控えめに感じるのですが、内部処理的にPascalっぽくなっているのでしょうか? C++の影響も受けているので、template, generics, macroなど不穏な機能も豊富です。

コード例

フィボナッチ数列を計算して標準出力に出力するコードはこんな感じです。はてなブログシンタックスハイライトがNimに対応してない*2のでGistを貼り付けます。
proc fib(n: int): int =
if n < 2:
return n
else:
return fib(n - 1) + fib(n - 2)
echo(fib(30))
view rawfib.nim hosted with ❤ by GitHub
個人的には行末セミコロンとか括弧のブロックとか好きではない(つまりPythonが好き)ので、インデントを使った構文は非常に好感触です。 あと、簡単に試しただけですが、とにかく速かったです。

2015年2月22日 追記

フィボナッチ数列を計算するだけですが、ベンチマークやりました。

開発の状況

記事執筆現在(2015年1月12日)の最新版は Version 0.10.2 です。 まだ正式リリース(Version 1.0)にはなっていませんが、Roadmap をみると言語仕様はある程度固まっているようです。
GithubのRepositoryを見ると、非常に活発に開発が行われています。 GithubのIssueForumにも頻繁に投稿があり、コミュニティも活発なようです。
コミット数の時系列グラフを見るとコミット数は増加傾向で、開発はどんどん活発になっているようです。
f:id:h-miyako:20150113121233p:plain

コンパイラのインストール

前置きが長くなってしまいました。
公式サイトのダウンロードページ通りの方法で上手く行くと思います。 いずれの方法でもnim --versionでバージョンが表示されればOKです。

バイナリ利用

これが一番簡単な方法だと思います。
  1. nim-0.10.2.zip を例えば ~/src にダウンロード
  2. 展開
  3. sh build.sh を実行
  4. ~/src/nim-0.10.2/bin にPATHを通すか、bin/nimをパスの遠たディレクトリに置く
例:~/srcにソースとバイナリを置く場合
cd ~/src
wget http://nim-lang.org/download/nim-0.10.2.zip
unzip nim-0.10.2.zip && cd nim-0.10.2
sh ./build
最後に~/src/nim-0.10.2/bin にPATHを通してください。 または、PATHの通っているディレクトリに実行ファイル(bin/nim)をリンクしてください。 私は~/binにPATHが通してあるので、ln -s $HOME/src/nim-0.10.2/bin/nim $HOME/bin/nim しました。

Githubのソースからインストール

開発版を試したりしたい場合はこちらです。 バイナリを利用する場合よりも多少ビルドに時間がかかりますが、 ダウンロードページ の手順通りで上手く行きました。

Hello world という名のコンパイラ動作確認

適当なディレクトリでhello.nimを作成し、中に
echo "Hello, world!"
と書いて保存します。
nim compile --run hello.nimを実行すると、コンパイル処理の後にHello, world!と表示されるはずです。
この時、同じディレクトリにhelloという実行可能バイナリとnimcacheというディレクトリができているはずです。 ./helloでシェルから直接このバイナリファイルを実行してもHello, world!と表示されます。 nimcacheの中には、nimが自動生成したCのコードなどが出力されています。
nimコマンドでは多くのエイリアスが使えます。先ほどの例では、compileの短縮形のc--runの短縮形の-rを使ってnim c -r hello.nimと短く書くことができます。
--run (-r)をつけなければ、バイナリファイルが作られるだけで実行はされません。 また、この時作成されるバイナリファイルはデバッグ用の機能も含まれているので、配布したりベンチマークをする時は-d:releaseオプションをつけてコンパイルします。
その他、コンパイラのオプションはnim --helpNim Compiler User Guideを参照してください。User Guideではより多くの(実験的な)機能も紹介されています。ReSTからHTMLやTeXを生成したり(モジュールのマニュアル作成用っぽい)、クロスプラットフォーム/クロスアーキテクチャコンパイルも可能(実装途中?動作未確認)です。

エディタの設定

EmacsVimをはじめ、Sublime TextやAtomなど多数のエディタ用プラグイン/設定が提供されています。 コンパイラのオプションでIDEに必要そうな機能も提供されており、これを使えばVimEmacsプラグインなども(比較的)簡単に作れそうです。 補完プラグインなど作ってみると面白いかもしれませんね。
また、Nimで書かれた専用のIDE Aporia もあります *3 。

Vimの設定

私はVimを使っているので、Vimの設定だけ紹介します。
まず、zah/nimrod.vimをインストールします。これはほぼ必須です。これで、シンタックスハイライト・自動インデント・ジャンプ機能等、が有効になります。
他の設定(主にプラグインの設定)は長くなったので別記事にまとめました。興味のある方はご参照ください。

Nimの構文

Nimの構文は行末セミコロンがなく、インデントを使ってブロックを表すので、パッと見はPythonに似ています。 特に条件分岐(if-else)やループ(for, while)の構文はPythonそっくりです。
せっかくチュートリアルなどを読んだので、ExampleにあったFizzBuzzにコメントを入れつつ色々な記法を織り交ぜて書き換えてみます。
# これはコメント
const f: string = "Fizz" # 定数(変更不可)
var b = "buzz" # 変数(変更可) 型指定は必須ではない
b = "Buzz" # 変数の値を変更
for i in 1..100: # 1から100までforループ
if i mod 15 == 0: # == で比較
echo(f & b) # 文字列連結(&) して標準出力へ
elif i mod 5 == 0: # else if な時はPython同様elif
echo b # echoは括弧なしでもOK
elif i mod 3 == 0:
f.echo() # これはecho(f)と同じ。メソッドチックな書き方
else:
i.echo # 引数が一つの時は、空の()を省略できる
view rawfizzbuzz_mod.nim hosted with ❤ by GitHub
構文のまとめというかメモをマニュアルやチュートリアルを見て試しながら書いていたのですが、非常に長くなりそうな上にまだ執筆途中なため、別の記事かGistかQiitaあたりに投稿します。
書きかけですが、とりあえず現状のものをGistに置きました。随時更新予定です。間違いなどありましたらご指摘いただけると幸いです。

最後に

何度も書くようですが、本当に書きやすくて手軽につかえて速度も出るので、もっともっと流行って欲しいです。この記事が、Nimを使う人を一人でも増やすきっかけになれば幸いです。
*1:公式のチュートリアルの前半 ((後半はこちら) と Nim by Example を眺めてみた程度
*2:GithubもQiitaもNimに対応してますよ!
*3:2015年1月11日現在、EclipseNetBeansIntelliJ IDEA用のプラグインは提供されていないようです。

0 コメント:

コメントを投稿