【本記事の目的】
こちらは、Nimのリリースバージョンごとの主要な変更を
日本語で記録して、後から追いやすくする為のメモです。
リリースごと更新予定です。
ちなみにAtCoderはNim 1.0.6へアップデートされました!
現在の最新リリースVersion
正式リリース: 1.2.4
devel(開発途上): 1.3.1
1.2.4
まとめ中。。。
1.2.2
リリース日: 2020/6/17
変更はバグ修正のコミット70件のみ
主なバグ修正
-
完了したFutureの最後の一つが未完了のままになってしまう
-
型付きPragmaをProc型に使用できない
-
opensslラッパーがOpenSSL 1.1.1f + Androidでスタックを破壊する
!! -- [ 加筆中 ] -- !!
1.2.0
リリース日: 2020/4/3
Version 1.2 Released
今回の変更は結構大きな変更があるようで、全てのユーザーにアップデートして使って欲しいとのことが公式ブログで書かれています。
Nim v1.2.0 概要
ちなみに最速でアップしてくださっていた上記の記事に感謝しつつ
特に新しいsugarマクロ + GC:ARCについては上記からほぼ引用させて頂いています。
m(_ _)m
1.2.0へのアップデート
Choosenimで
# まずはchoosenimもアップデートされているので自身もアップデートしましょう
$ choosenim update self
# いつも通りのコマンドでNimを1.2.0へ
$ choosenim update stable
その他パッケージマネージャで
# Homebrew(MacOS)
$ brew update nim
# scoop(Windows)
$ scoop update nim
# Linuxはいっぱいあるので割愛。普通にnimを指定してアップデートすればOK
主な変更点
useVersion オプション
以前の実装がv1.0に依存している場合、--userVersionオプションを使うことで
v1.2のNimでv1.0のシミュレートをすることができます。
例えば1.2ではproc型の型変換が厳密になっています。
もし正しく動作しない場合はこちらのIssueに起票してください。
例
$ nim c --useVersion:1.0 target.nim
declaredを使ったv1.0とv1.2の使い分け
ライブラリの作成者は when declared の記述を使うことで
v1.0とv1.2の定義を使い分けることができます。
import sequtils
when not declared(unzip):
proc unzip*[S, T](s: openArray[(S, T)]): (seq[S], seq[T]) =
result[0] = newSeq[S](s.len)
result[1] = newSeq[T](s.len)
for i in 0..<s.len:
result[0][i] = s[i][0]
result[1][i] = s[i][1]
let a = @[('a', 1), ('b', 2), ('c', 3)]
let b = unzip(a) # version 1.0 では上記で宣言したunzipが使われる
# version 1.2 ではsequtilsライブラリのunzipが使われる
assert b == (@['a', 'b', 'c'], @[1, 2, 3])
新しいsugarマクロ
Collect
- collectマクロは seq/set/table の内包に役立つ
- lc(リスト内包)の代替でlcよりも慣用的で強力
- collectの使用にオーバーヘッドはない
import sugar
let numbers = collect(newSeq): # or: collect(newSeqOfCap(10))
for i in 1..10:
i
assert numbers == @[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
import tables, sugar
let oddSquares = collect(initTable):
for i in numbers:
if i mod 2 == 1:
{i: i * i}
assert len(oddSquares) == 5
assert oddSquares[7] == 49
import sets, sugar
let oddOrNegative = collect(initHashSet):
for i in numbers:
{if i mod 2 == 1: i else: -i}
assert 5 in oddOrNegative
assert 2 notin oddOrNegative
assert -2 in oddOrNegative
Dup
- dupマクロはin-place関数に対して使うことで入力変数を変更せずに結果を返すようにすることができる。
- 将来的には、in-placeバージョンのみが提供されるようになる可能性がある。(現在はsortと- - sortedなどin-placeとout-of-placeの2種類の関数が用意されている場合がある)
import sugar
proc makePalindrome(s: var string) =
for i in countdown(s.len-2, 0):
s.add(s[i])
var a = "abc"
makePalindrome(a)
assert a == "abcba"
var b = "xyz"
var c = b.dup(makePalindrome)
assert b == "xyz"
assert c == "xyzyx"
アンダースコア_によって、引数を渡す場所を示すことができる。
import algorithm, sugar
# b = "xyz"
var d = dup b:
makePalindrome # xyzyx
sort(_, SortOrder.Descending) # zyyxx
makePalindrome # zyyxxxyyz
assert d == "zyyxxxyyz"
Capture
- captureはループ内でループカウンタの値を用いたクロージャーの作成に有用
- イベント処理や{int: callBack}ルックアップテーブルに使用可
import strformat, sugar
var myClosure: proc(): string
for i in 5..7:
for j in 7..9:
if i * j == 42:
capture i, j:
myClosure = proc (): string = fmt"{i} * {j} = 42"
let a = myClosure()
assert a == "6 * 7 = 42"
GC:ARC
- --gc:arcが新機能としてリリース
- FOSDEM 2020で開発者(Araq)が背景の説明と利点を示すベンチマークを示している。
- C++やRustのSemanticsから影響を受けている。
- もっと詳細な説明は後日でるかも。
その他の主な変更
strformatモジュール
- { と } 以外の指定した文字を使用できるfmtのオーバーロード関数の追加
tableモジュール
- 新しいprocを追加:
- OrderedTable.pop
- CountTable.del
- CountTable.pop
- Table.pop
- 各テーブル.take() (バグ修正に書いてありましたが一応)
osモジュール
-
OSごとのパス判定を行う際、追加のサニタイズをできるよう lastPathPart を追加
(原文には Added os.normalizePathEnd for additional path sanitization.って書いてあるけどコミット内容的にはlastPathPartの追加でnormalizePathEndは変更って感じ) -
パスが相対的に正しいか判断するための isRelativeTo
isRelativeTo("./foo//bar", "foo")
isRelativeTo("foo/bar", ".")
timesモジュール
-
fromUnix,toUnixの1秒未満バージョンの以下が追加
- fromUnixFloat
- toUnixFloat
-
うるう年の2/29か判定する isLeapDay を追加
sequtilsモジュール
- sequtilsモジュールへ以下を追加
- minIndex
- maxIndex
- unzip
httpclientモジュール
- MultipartDataをstringに変換する $ procが追加されました
htmlgenモジュール
- MathMLサポートを追加しました
sequtilsモジュール
- countIt procを追加しました
macrosモジュール
- withを追加しました。これは同じ第一引数をとるような関数をまとめるために有効です。
import std/with
type
Foo = object
col, pos: string
var f: Foo
# どちらも Foo型を第一引数としています。
proc setColor(f: var Foo; r, g, b: int) = f.col = $(r, g, b)
proc setPosition(f: var Foo; x, y: float) = f.pos = $(x, y)
# このようにそれぞれの proc に第一引数として共通のfを渡すことができます。
with(f, setColor(2, 3, 4), setPosition(0.0, 1.0))
echo f
let numbers = @[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
assert numbers.countIt(it < 0) == 3
コンパイラ関連
-
生成されたJavaScriptのコードは、スペースとタブを混在ではなくスペースを使用するようになります。
-
--panics:on オプションの追加
- IndexErrorやOverflowErrorなどの実行時エラーが、tryではキャッチできない致命的なエラーに変わります。
- --panics:onは、プログラムのランタイム効率とコードサイズを大幅に改善できます。
-
constの暗黙の変換が正しく動作するようになりました。
const SOMECONST = 0.int; procThatTakesInt32(SOMECONST) # ❌
const SOMECONST = 0 # ⭕️
-
{.dynlib.}プラグマは、POSIXおよびmacOSで共有オブジェクトを作成するときにシンボルをエクスポートするために必要になり、Windowsでの動作と同様になりました。
-
オーバーフローを検出するより高速な方法を実装。
- GCCの一部のバージョンにはこの機能が無く確実でないため、"undefined reference to __builtin_saddll_overflow" のコンパイルエラーが出た場合には -d:nimEmulateOverflowChecks を使用してプログラムをコンパイルしてください。
-
コンパイラオプションを指定できるcompilesettingsを追加
type
# 一つの値をセットするオプション
SingleValueSetting* {.pure.} = enum
arguments, ## experimental: the arguments passed after '-r'
outFile, ## experimental: the output file
outDir, ## the output directory
nimcacheDir, ## the location of the 'nimcache' directory
projectName, ## the project's name that is being compiled
projectPath, ## experimental: some path to the project that is being compiled
projectFull, ## the full path to the project that is being compiled
command, ## experimental: the command (e.g. 'c', 'cpp', 'doc') passed to
## the Nim compiler
commandLine, ## experimental: the command line passed to Nim
linkOptions, ## additional options passed to the linker
compileOptions, ## additional options passed to the C/C++ compiler
ccompilerPath ## the path to the C/C++ compiler
# 複数の値をセットできるオプション
MultipleValueSetting* {.pure.} = enum
nimblePaths, ## the nimble path(s)
searchPaths, ## the search path for modules
lazyPaths, ## experimental: even more paths
commandArgs, ## the arguments passed to the Nim compiler
cincludes, ## the #include paths passed to the C/C++ compiler
clibs
!! -- [ 加筆中 ] -- !!
言語的変更
-
C/C++ の alignas 宣言修飾子と同様に{.align.}プラグマを変数とオブジェクトフィールドに適用できるようになりました。
(alignas は変数をメモリ上の特定の位置に配置するよう要求する修飾子です) -
左辺値参照の新しい構文が追加されました。詳しくはこちらのリファレンス
import dcls
var b {.byAddr.} = expr
主なバグ修正
-
OpenBSDで os.getAppFilename() が誤った値を返す問題
-
Table以外のOrderedTableやCountTableにtake()がない問題 (これバグなのか?)
!! -- [ 加筆中 ] -- !!
1.0.6
リリース日:2020/1/25(~~まだchoosenim stableには来てない?~~来ましたね!)
1.0.6 Changelog
今回も基本的にはバグ修正。
個人的にはdb_mysqlのgetRowが改善されたのは嬉しい。
主なバグ修正
- --styleCheck:errorをつけた際のstdlibのスタイル不具合
- new(ref MyObject)関数がコンパイル時に評価されない
- orderedTable().del()を初期化してないTableに対して実行するとクラッシュする
- マイナス値に * 0するとクラッシュする
- for文内のStatic[T]がコンパイル時にクラッシュする
- JSバックエンドコンパイル時にmoveメソッドがundefinedエラー
その他のバグ修正
- db_mysqlのgetRows()関数で対象のカラムがnullの時エラーを起こす
ドキュメントの改善
各種修正
1.0.4
リリース日:2019/11/26
1.0.4 Changelog
言語的な変更
-
unsigned integerは実行時にはチェックされず、以前のNimバージョンを踏襲します。特殊なケースのため、ドキュメントも更新されました。
詳細はこちら RFCs/issues/175 -
外部コマンドを取り入れる際の判定OS種別に、ArchLinuxと並んでManjaroを追加しました
-
--os:iosは暗黙的にosxもしくは、macosxの定義が必要になりました
-
nim.cfgのパーサーをエクスポートできるようにしました(readConfigFileをimportできるようにしたみたい)
バグ修正
以下の問題を修正しました。
- gorge(Ex)を何回か呼び出すと失敗するようになる問題
- posix moduleの改善(posix_utilsの追加やドキュメンテーションコメントの整備など)
- 低レベル算術結果のバグ(特に減算?)
- strformat, asyncdispatch, constを一緒に使うとコンパイルエラーになる
- NimblePathが追加的である問題の修正(--creatrNimblePathが追加された様子。個々人の.nimbleに依存しない形での開発改善みたい)
wip...
ドキュメントの改善
- Mathモジュールをドキュメント化しました
- ドキュメントのいくつかの壊れたリンクなどを修正しました
- sequtilsのexampleコード内の非推奨randomをrandに変更しました
wip...
1.0.2
リリース日:2019/10/23
基本的にバグフィックスのみです。
・「nim check」を走らせた際に「Assertion Error」が表示される問題を修正
・Javascriptでrandom.randomize()がエラーになる問題を修正
1.0.0
リリース日:2019/9/23
後方互換性に影響する変更
・-d:nimBinaryStdFilesオプションがなくなり
stdin, stdout, stderrは再度バイナリファイルになりました。(Windowsのみ)
標準ライブラリの破壊的変更
・unicode.Rune16は削除されました(使用用途が基本的にない)
使用する場合は以下を宣言してください
type
Rune16* = distinct int16
ライブラリの変更
- まだ安定版では無いが追加されたAPI
- std/varints
- core/allocators
- core/hotcodereloading
- asyncstreams
- base64
- browsers
- collections/rtarrays
- collections/sharedlist
- collections/sharedtable
- concurrency/atomics
- concurrency/cpuload
- concurrency/threadpool
- coro
- endians
- parsesql
- pathnorm
- reservedmem
- typetraits
言語への追加
・importjsプラグマが追加されました。
・インラインのiteratorでのlent Tの返却がサポートされました。
# 例:
iterator myitems[T](x: openarray[T]): lent T
iterator mypairs[T](x: openarray[T]): tuple[idx: int, val: lent T]
言語の変更
・uint64は正しい値が取得できるようになりました。
ツールの変更
・Nimコンパイラは「nim c -r」で変更のないファイルは再コンパイルしなくなりました。
再コンパイルする場合は「--force-build」オプションを使用してください。
・未使用のモジュールで警告が表示されるようになりました。
表示したくない場合は{.used.}プラグマをモジュールファイルの先頭で宣言してください。
・テストツールの名称が「tester」から「testament」に変更されました。