Nim v2.0 リリース!
こちらの公式記事を要約、日本語化しております。
Nim v2.0 released
何が大きく変わったのか
- GCのARC/ORCアルゴリズム改良が完成!
- タプル型の代入がより直感的かつネスト可能に
- 型推論にトップダウン推論を対応
- オーバーロード可能なEnum
- オブジェクト宣言時にデフォルト値を設定可能に
- 型不一致の際のエラーメッセージがわかりやすく
1. GCのARC/ORCアルゴリズム改良が完成!
語弊を恐れずにわかりやすくすると、
Rustのような厳格なメモリ管理が特別に意識せずGCで行えるようになりました。
実はv1.4からARC/ORCについての対応は進んできていました。
そちらが今回改良も含めて完成したということですね!
NimはRustと比較されることが多いので、例として挙げさせていただきましたが
Rustの所有権の概念と同じように、確保した変数メモリがスコープを抜けると
解放されるようになっています。
つまりコンパイル時にコンパイラからスコープを判定してデストラクタを入れています。
ARC, ORCはどちらもGCのためRustの障壁となる学習コストをかけずに
GCにお任せしつつ効率的なメモリ管理ができます。
ORCの詳しいアドバンテージについては、素晴らしい記事があるのでこちらを...!
Nimのメモリ管理を理解する④ ― ORC - アルゴリズムによるアドバンテージ
2. タプル型の代入がより直感的かつネスト可能に
proc returnsNestedTuple(): (int, (int, int), int, int) = (4, (5, 7), 2, 3)
# Tuple型のネストが展開でも使用可能!
let (x, (_, y), _, z) = returnsNestedTuple()
お、Qiitaのコードスニペットもまだv2.0に対応していないので、エラーになってますね。
3. 型推論にトップダウン推論を対応
これまでは下記のような複雑な型チェックはコンパイルできませんでしたが、
v2.0からコンパイル可能になりました。
let foo: seq[(float, byte, cstring)] = @[(1, 2, "abc")]
4. オーバーロード可能なEnum
具体的には外部ライブラリと同名のパラメータとの曖昧性回避などにに役立ちます。
type
E1 = enum
value1, value2
E2 = enum
value1, value2 = 4
const
Lookuptable = [
# 曖昧性の回避
E1.value1: "1",
value2: "2"
]
5. オブジェクト宣言時にデフォルト値を設定可能に
こちらは他の言語だとお馴染みでしたが、今までは宣言時にデフォルト値を入れることができなかったため便利になりました。
type
Rational* = object
num: int = 0
den: int = 1
var r = Rational()
assert $r == "(num: 0, den: 1)"
6. 型不一致の際のエラーメッセージがわかりやすく
proc foo(s: string) = discard
proc foo(x, y: int) = discard
proc foo(c: char) = discard
foo 4
上記コードを実行したときのエラー出力が下記のように表示されるようになります。
temp3.nim(11, 1) Error: type mismatch
Expression: foo 4
[1] 4: int literal(4)
Expected one of (first mismatch at [position]):
[1] proc foo(c: char)
[1] proc foo(s: string)
[2] proc foo(x, y: int)
標準ライブラリがnimbleに移動したので下記でインストールするように変更されました
# 例:
$ nimble install punycode
# パッケージ名の移動
std/punycode => punycode
std/asyncftpclient => asyncftpclient
std/smtp => smtp
std/db_common => db_connector/db_common
std/db_sqlite => db_connector/db_sqlite
std/db_mysql => db_connector/db_mysql
std/db_postgres => db_connector/db_postgres
std/db_odbc => db_connector/db_odbc
std/md5 => checksums/md5
std/sha1 => checksums/sha1
std/sums => sums