Nim - Release Features - リリース変更履歴

#####  【本記事の目的】
こちらは、**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](https://nim-lang.org/blog/2020/04/03/version-120-released.html)
今回の変更は結構大きな変更があるようで、全てのユーザーにアップデートして使って欲しいとのことが公式ブログで書かれています。

[Nim v1.2.0 概要](https://qiita.com/tauplus/items/1fa09b153555c29f8074)
ちなみに最速でアップしてくださっていた上記の記事に感謝しつつ
特に新しいsugarマクロ + GC:ARCについては上記からほぼ引用させて頂いています。
m(_ _)m

### 1.2.0へのアップデート

**Choosenimで**

```shell
# まずはchoosenimもアップデートされているので自身もアップデートしましょう
$ choosenim update self

# いつも通りのコマンドでNimを1.2.0へ
$ choosenim update stable
```

**その他パッケージマネージャで**

```shell
# 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](https://github.com/nim-lang/Nim/issues)に起票してください。

**例**

```shell
$ nim c --useVersion:1.0 target.nim
```

### declaredを使ったv1.0とv1.2の使い分け
ライブラリの作成者は when declared の記述を使うことで
v1.0とv1.2の定義を使い分けることができます。

```nim

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の使用にオーバーヘッドはない

```Nim
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種類の関数が用意されている場合がある）

```Nim
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"
```

アンダースコア_によって、引数を渡す場所を示すことができる。

```Nim
import algorithm, sugar

# b = "xyz"
var d = dup b:
  makePalindrome  # xyzyx
  sort(_, SortOrder.Descending)  # zyyxx
  makePalindrome  # zyyxxxyyz

assert d == "zyyxxxyyz"
```

**Capture**

- captureはループ内でループカウンタの値を用いたクロージャーの作成に有用
- イベント処理や{int: callBack}ルックアップテーブルに使用可

```Nim
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

```Nim:例
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を追加しました。これは同じ第一引数をとるような関数をまとめるために有効です。

```Nim:例
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
```



```Nim:例
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の暗黙の変換が正しく動作するようになりました。

```Nim:例
const SOMECONST = 0.int; procThatTakesInt32（SOMECONST） # ❌
const SOMECONST = 0 # ⭕️
```

- {.dynlib.}プラグマは、POSIXおよびmacOSで共有オブジェクトを作成するときにシンボルをエクスポートするために必要になり、Windowsでの動作と同様になりました。

- オーバーフローを検出するより高速な方法を実装。
    - GCCの一部のバージョンにはこの機能が無く確実でないため、"undefined reference to __builtin_saddll_overflow" のコンパイルエラーが出た場合には -d：nimEmulateOverflowChecks を使用してプログラムをコンパイルしてください。

- コンパイラオプションを指定できるcompilesettingsを追加

```Nim:オプション例
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 は変数をメモリ上の特定の位置に配置するよう要求する修飾子です）

- 左辺値参照の新しい構文が追加されました。詳しくは[こちらのリファレンス](https://nim-lang.org/docs/decls.html#byaddr.t%2C%2C%2C)

```Nim:例
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](https://github.com/nim-lang/Nim/commit/89b39ee8fe271d0e1b75c15a4c6cf82eb9c13aea)

今回も基本的にはバグ修正。
個人的には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](https://github.com/nim-lang/Nim/blob/version-1-0/changelogs/changelog_1_0_4.md)

##### 言語的な変更

- unsigned integerは実行時にはチェックされず、以前のNimバージョンを踏襲します。特殊なケースのため、ドキュメントも更新されました。
[詳細はこちら　RFCs/issues/175](https://github.com/nim-lang/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は削除されました（使用用途が基本的にない）
使用する場合は以下を宣言してください

```Nim
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の返却がサポートされました。

```Nim
# 例：
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」に変更されました。