matobaの学んだこと

とあるPythonエンジニアのブログ。ソフトウェア開発、執筆活動、ライフログ。

興味本位でNimを少し触った

興味本位で、Nimってプログラミング言語を触ってみた。

Nim ?

プログラミング言語の一つ。

nim-lang.org

GolangとかRustとかとなんか比較されてるような雰囲気がある。

コンパイルして使うタイプの言語で、めっちゃ速いらしい。

なぜ、Nimを

なんか、Webでイケてるって推してたから。たまにはPythonじゃない言語を書いてみようとするのもいいかなーと思った。

あと、Pythonの影響を受けた文法になってるとか、メンドくさがり屋の人たちが作ってるとかいうのを記事で読んだから。

install

macOSで動かして見た。brewでインストールできる。

brew install nim

ここら辺を見ると、UNIX周りのパッケージマネージャーにきちんと入ってそうな印象があった。

Unix installation | Nim

僕は、深く考えずに、macOSにそのままbrewでインストールした。

hello world

とりあえずhello worldするところからやる。

こんな感じにかける。

echo "hello world."

コンパイルはこうする。

$ ls
hello.nim
$ nim compile hello.nim
Hint: used config file '/usr/local/Cellar/nim/0.19.0/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: hello [Processing]
Hint:  [Link]
Hint: operation successful (12268 lines compiled; 0.178 sec total; 16.383MiB peakmem; Debug Build) [SuccessX]

すると、 hello という実行ファイルができる。

$ ls
hello     hello.nim

普通に実行できる。

$ ./hello
hello world.

ちなみに --run オプションをつけるとコンパイルして実行できる。

$ nim compile --run hello.nim
Hint: used config file '/usr/local/Cellar/nim/0.19.0/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: hello [Processing]
Hint:  [Link]
Hint: operation successful (12268 lines compiled; 0.412 sec total; 16.367MiB peakmem; Debug Build) [SuccessX]
Hint: /Users/mtb/programing/nim/hello  [Exec]
hello world.

変数を定義する

変数の定義は、こんな感じ。

var name: string = "mtb"

name という変数をstring型で定義して、mtb という文字列を格納している。

こういうファイルを作って、

var name: string = "mtb"
echo name

実行すると、こうなる。

$ nim compile --run var_define.nim
Hint: used config file '/usr/local/Cellar/nim/0.19.0/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: var_define [Processing]
Hint:  [Link]
Hint: operation successful (12269 lines compiled; 0.440 sec total; 16.371MiB peakmem; Debug Build) [SuccessX]
Hint: /Users/mtb/programing/nim/var_define  [Exec]
mtb

var で定義すると変数ですが、 const をつけると定数になる。 let をつけると再代入禁止な変数を作れる。

ifの書き方

ifはこんな感じでかける。Pythonと同じくifはインデントで表す様子。スペースの数はよくわかってないけど、公式ドキュメントでは2つだった。

var name : string = "mtb"

if name == "":
  echo "who are you?"
else:
  echo "hello " , name , "."

実行するとこうなる。

$ nim compile --run if_sample.nim
Hint: used config file '/usr/local/Cellar/nim/0.19.0/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: if_sample [Processing]
CC: if_sample
Hint:  [Link]
Hint: operation successful (12273 lines compiled; 0.218 sec total; 16.383MiB peakmem; Debug Build) [SuccessX]
Hint: /Users/mtb/programing/nim/if_sample  [Exec]
hello mtb.

なんとなくわかるけど、インデントがずれてると、コンパイルエラーが出る。

var name : string = "mtb"

if name == "":
    echo "who are you?"
else:
       echo "hello " , name , "."
    echo "this is invalid indent."
$ nim compile if_sample.nim
Hint: used config file '/usr/local/Cellar/nim/0.19.0/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: if_sample [Processing]
if_sample.nim(7, 5) Error: invalid indentation

Boolean, Strins, Charcter, Integer, floatが基本の型。

あと、set, range, array, sequence, ... とか色々な複数の変数を持てる型があった。

とりあえず、どんな計算をさせたいのかによって使う型が変わるのかなーとか思った。

for の書き方

forはこんな風にかける。

var myArray : array = ["note1", "note2", "note3"]
for i in myArray:
  echo i

array型に入れて、forで回せる。Pythonっぽい。

$ nim compile for_sample.nim
... 略
$ ./for_sample
note1
note2
note3

ちなみに、変数はキャメルケースで書くらしい。

関数

こんな風に書ける。 proc はpythonでいうdef みたいな宣言。 add の部分が関数名。 int = の部分は戻り値の型宣言。

proc add(a: int, b: int): int =
  return a + b

echo add(1, 3)

当たり前だけど実行するとこうなる。

$ nim compile func_sample.nim
... 略
$ ./func_sample
4

FizzBuzz

FizzBuzzを書いて見た。もっと素直にかけるんだろうけど今回はこう書いて見た。

proc fizzbuzz(num :int): string =
  var result: string = ""
  if num mod 3 == 0:
    result = "Fizz"
  if num mod 5 == 0:
    result = result & "Buzz"

  if result == "":
    return $num
  else:
    return result


for num in countup(1, 30):
  echo fizzbuzz(num)

変数名に $ をつけると文字列に変換されるらしい。 文字列の連結は、& を使うらしい。

感想。

インデントとifの書き方とかPythonっぽかった。

システムプログラミングで使うらしい。

Webサーバーを自分で作るぞー!とかそういうテンションで使うものの様子。

ソケットプログラムするときに使うのだろうと思う。

低レイヤーの何かを触る機会があったら、また勉強して見たいなーと思った。(ただし、そんな機会は来ないかもしれない)

見たWebの記事