軌跡にはパンくずを

戻れるように置くのです

Cは嫌だ?でも速度が欲しい?なら「Nim」を学ぶのです

これはUEC Advent Calendar 2018 1日目の記事です。

お陰様で1日目にしてカレンダーが全て埋っています。参加表明してくださった方々、ありがとうございます。
今日から毎日いろんな人の記事が読めるみたいですよ。楽しみですね。

今日は記念すべき1日目なので、Nimを知らずに人生を損している皆様のためにも、Nimの紹介をしようと思います。


Nimとは

Nimは今後流行ればいいなと個人的に思っているプログラミング言語のひとつです。

Nimのおすすめな点は

Rubyのようなわかりやすい構文で書けて
C言語に迫る実行速度を実現できる
夢のようなコンパイル言語

と言えます。 とにかくこのことだけでも覚えてもらえれば僕はもう満足です。


さて紹介するにあたって、ただNimのソースコードを見せられて「すごいすごい」言われても、その凄さを実感できないと思います。

ここでは基礎プロ*1で慣れ親しんでいるであろうRuby と 基礎プロの後半に習うC言語(以降C)の構文を比較しながらNimの良さを書いていきます。


構文比較

一応注意として、この記事は構文を覚えるために書かれていません。

そういうわけなので、なんとなく各言語間の違いがわかってもらえれば大丈夫です。気楽に見てくださいな。

上から順にNim、Ruby、Cのコードになります。


コメント

まずはコメントアウトから見ていきましょう。

# これは1行コメント
#[
複数行
コメント
]#
# これも1行コメント
=begin
複数行に
渡って
書けます
=end
// 驚くべき証明を見つけたが、この一行はそれを書くには狭すぎる.
/*
なら
ここに
書けばいいじゃない(証明終了)
*/

1行コメントはNimとRubyで同じです。親近感湧きません?


標準出力

改行入りの標準出力の比較です。

echo("HelloUEC!")  # echo "HelloUEC!" でも可
puts("HelloUEC!")  # puts "HelloUEC!" でも可
puts("HelloUEC!");  // いつものなら printf("HelloUEC!\n");

Cは文末にセミコロン";"が必要です.。これがあることで文の終わりだと理解します。
逆にRubyやNimは改行で判断しているため、忘れやすいセミコロンが必要ないです。

Nimのechoはコンリテ*2で扱ったターミナルコマンドと同じなので、馴染み深いのもポイント高いですね。


変数宣言と代入

var a: int
a = 1
a = 1
int a = 1;

Nimは型推論という機能が備わっているため、int(整数)という型を明示せずとも

var a = 1

で書けます。セミコロンない分Cより楽できます。

Rubyは動的型付け言語なので型を書く必要がありません。
その代わりに実行速度が落ちます。そうは言っても基礎プロで扱う内容なら気にならないレベルです。


条件分岐

var b = 3
if b == 1:
    echo "1だよ"
elif b == 2:
    echo "2じゃん"
else:
    echo "みそスープ"
b = 3
if b == 1 then  # thenは省略可
    puts "1だよ"
elsif b == 2 then
    puts "2じゃん"
else
    puts "みそスープ"
end
int b = 3;
if (b == 1) {
    printf("1だよ\n");
} else if (b == 2) {
    printf("2じゃん\n");
} else {
    printf("みそスープ\n");
}

Cの"{}"はif文がどこからどこまでのまとまりかを判別するために使われています。コメント欄でのご指摘の通り、"{}"内の命令(この例だとprintf)が1つの時は"{}"を省略することができます。

Nimだとこれがコロン":"とインデント(字下げ)で、

Rubyならthenとend(またはインデントとend)で判別しています。

Cの場合、括弧で囲まれていればどの位置に書いても構文上の問題はないです。
この"{}"をどこに書くかは結構好みが分かれるところでして、僕のおすすめとしては "{}"や";"を何文も連ねて書くときに使える隅寄せお掃除術*3で綺麗にするやり方ですね。寄せたものは揃えるようにするとゴミ感が出なくてなお良いですよ。

f:id:puman03:20181201153331p:plain

"{}"だとこんなおかしな書き方も生まれてしまいますが、コロン:とインデントならこんなことは起きません。コードを書く人が違っても書き方は同じになるので、そこもNimの利点であると言えます。


繰り返し文

var c = 1000
while 0 <= c and c <= 1000:
    c -= 7  # c = c - 7 と同じ
    echo c
c = 1000
while 0 <= c && c <= 1000 do
    c -= 7 
    puts c
end
while (0 <= c && c <= 1000) {
    c -= 7;
    printf("%d\n", c);
}

while文で比較しました。言いたいことは条件分岐と同じですがこのwhile文内の"{}"で囲まれた命令は複数(減算とprintf)なので、"{}"が必要です。(if文で話したお掃除術は"{}"が省略できないwhile文でするべきでした。あとで直しておきます)

今回の構文比較を通して、わかりやすい構文の具体例ならRubyを挙げても間違いではないです。しかし、記述上の近さで言ったらPythonというプログラミング言語の方がNimに似ています。例えばwhile文やif文なら、NimとPythonは同じ構文で書くことが出来ます。


Nimについてのあれこれ

もしこの記事で少しでも興味を持って頂けたのなら、以下のサイトを参考にするといいと思います。

導入

Nim言語感想&概説
どんな言語なのか特徴がわかりやすくまとめてあります。

Nimを導入しよう! | 東京工業大学デジタル創作同好会traP
macOS Windows Ubuntu Arch Linux での環境構築方法が載っています。

至高の言語、Nimを始めるエンジニアへ
いざ始めようと思った時にこの記事を足掛かりにすると良さそうです。

構文

Syntax of Nim
NImの構文がよくまとまっています。ここで紹介してない構文がたくさんあるので見て見てください。

【Nim】個人的逆引きリファレンス
書き方を忘れたときの参照用です。

Documentation | Nim
公式ドキュメントです。Qiitaにチュートリアルのパート1の日本語訳があります。

他言語との実行速度比較

FizzBuzz を無駄にベンチマークしてみた By Nim、golang、Rust、Crystal、その他 - 強まっていこう

kostya/benchmarks: Some benchmarks of different languages

見てみればわかるのですが、Cには基本勝てないけどまあ早いよって感じです。


最後に

今回はNimがどちらかと言えばRubyに似ている構文だということに絞って紹介しました。

なんとなく似てることがわかってもらえたのではないでしょうか?

この記事がNimを触るきっかけになれば幸いです。


P.S.

「タイトルからベンチマークします感溢れ出てるのに他サイトに丸投げってどういうこと?」って苦情きてしまいそうですね。

でもいいんです。これが電通大クオリティ*4です。



2日目の担当は id:Knium さんです。

knium.hatenadiary.com

明日も楽しみですね。では。

*1:基礎プログラミングおよび演習の略。電通大一年後期の必修科目。

*2:コンピュータリテラシーの略。電通大一年前期の必修科目。

*3:散らかっている物を隅に寄せることで、お部屋をぱっと見綺麗に見せる簡単お掃除術のこと。ゴミではないので捨てられないときに有効。

*4:ここに独り言書くのっていかにもはてなブログ感あって好きです。一度やってみたかった。