Erlang/OTP 18.0の主な修正の詳細 #Erlang

## release news
[Erlang Programming Language Erlang/OTP 18.0 has been released](http://www.erlang.org/news/88)

## release news の日本語訳
[【翻訳】Erlang/OTP 18.0 has been released #Erlang - Qiita](http://qiita.com/KOU_CHANG/items/b54887313533396ccbe1)

## ライセンスがAPL2.0に変わった
APLはApache Public Licenseの略。
詳しくは[Wikipedia](https://ja.wikipedia.org/wiki/Apache_License)で。
（嘘を言っていても怖いので…。）
元々はErlang Public Licenseという独自のライセンスが使われていた。
[このあたり](https://erlang.g.hatena.ne.jp/kuenishi/20090418/1240028987)に日本語で情報が書かれていた。

## erts: 時間機能の拡張
http://www.erlang.org/doc/apps/erts/time_correction.html

### [新しい時間に関するAPI](http://www.erlang.org/doc/apps/erts/time_correction.html#The_New_Time_API)
互換性のために `erlang:now/0` は残すが、極力使わない方が良い

#### 新しいBIF
* [`erlang:convert_time_unit/3`](http://www.erlang.org/doc/man/erlang.html#convert_time_unit-3)
* [`erlang:monotonic_time/0`](http://www.erlang.org/doc/man/erlang.html#monotonic_time-0)
* [`erlang:monotonic_time/1`](http://www.erlang.org/doc/man/erlang.html#monotonic_time-1)
* [`erlang:system_time/0`](http://www.erlang.org/doc/man/erlang.html#system_time-0)
* [`erlang:system_time/1`](http://www.erlang.org/doc/man/erlang.html#system_time-1)
* [`erlang:time_offset/0`](http://www.erlang.org/doc/man/erlang.html#time_offset-0)
* [`erlang:time_offset/1`](http://www.erlang.org/doc/man/erlang.html#time_offset-1)
* [`erlang:timestamp/0`](http://www.erlang.org/doc/man/erlang.html#timestamp-0)
* [`erlang:unique_integer/0`](http://www.erlang.org/doc/man/erlang.html#unique_integer-0)
* [`erlang:unique_integer/1`](http://www.erlang.org/doc/man/erlang.html#unique_integer-1)
* [`os:system_time/0`](http://www.erlang.org/doc/man/os.html#system_time-0)
* [`os:system_time/1`](http://www.erlang.org/doc/man/os.html#system_time-1)

#### 拡張された既存のBIF
* [`erlang:monitor(time_offset, clock_service)`](http://www.erlang.org/doc/man/erlang.html#monitor-2)
* [`erlang:system_flag(time_offset, finalize)`](http://www.erlang.org/doc/man/erlang.html#system_flag_time_offset)
* [`erlang:system_info(os_monotonic_time_source)`](http://www.erlang.org/doc/man/erlang.html#system_info_os_monotonic_time_source)
* [`erlang:system_info(os_system_time_source)`](http://www.erlang.org/doc/man/erlang.html#system_info_os_system_time_source)
* [`erlang:system_info(time_offset)`](http://www.erlang.org/doc/man/erlang.html#system_info_time_offset)
* [`erlang:system_info(time_warp_mode)`](http://www.erlang.org/doc/man/erlang.html#system_info_time_warp_mode)
* [`erlang:system_info(time_correction)`](http://www.erlang.org/doc/man/erlang.html#system_info_time_correction)
* [`erlang:system_info(start_time)`](http://www.erlang.org/doc/man/erlang.html#system_info_start_time)
* [`erlang:system_info(end_time)`](http://www.erlang.org/doc/man/erlang.html#system_info_end_time)

### time warp modes
* システムの時間が変わった時にシステムの挙動を変える

#### 2.6 Time Warp Modes | time correction
http://www.erlang.org/doc/apps/erts/time_correction.html#Time_Warp_Modes

* オフセット時間を用いてErlang monotonic timeを加算することによって求める
* オフセット時間は使用するタイムワープモードに応じて異なった管理を行う
* `erl` コマンドのオプションは `+C [no_time_warp | single_time_warp | multi_time_warp]`

##### No Time Warp Mode
* ランタイムシステムの開始時に決定し、その後は変えない
* デフォルト
    * 今までのシステムはこの挙動と同じ
    * _だから仕方なくデフォルト…_

##### Single Time Warp Mode
* Preliminary Phase
    * 時間補正が有効な場合
        * OSのシステム時間とは別に一定周波数になるようにErlang monotonic clockを調整する
        * OSのシステム時間と乖離する可能性はある
    * 時間補正が無効な場合
        * No Time Warp Modeと同じ
* Final Phase
    * `erlang:system_frag(time_offset, finalize)`で時間を確定させる
    * ファイナライズは一度だけ行われる
    * OSのシステム時間と合うようにオフセットが調整される
この機能を適切に使うには2つの要件がある
1. 前方にワープできること
2. OSのシステムの時間が正確であること

###### Multi Time Warp Mode
* より好ましい構成
* ほぼすべてのプラットフォームで良い動作、良いスケールを行える
* オフセット時間はいつでも変更しうる
    * より正確な時間を使える

時間補正が無効になっている場合

* OSシステム時間が前方にワープするとErlang monotonic clockも前方にワープ
* OSシステム時間が後方にワープするとErlang monotonic 時間を短時間停止させる停止

## `-dialyzer()` 属性
http://www.erlang.org/doc/man/dialyzer.html#id60919
* dialyze時に警告を抑制するために使える

### ある関数の警告を抑制
```erlang
-dialyzer({nowarn_function, f/0}).
```

### improper lists に対する警告を抑制
```erlang
-dialyzer(no_improper_lists).
```

### warningオプションを抑制
```erlang
-dialyzer({no_improper_lists, g/0}).
-dialyzer({[no_return, no_match], [g/0, h/0]}).
```

### 警告をオンにする
```erlang
-dialyzer(unmatched_returns).
```

## POODLE脆弱性のためのTLS-1.0
TODO: 書く

## stdlib: supervisorのflagsとchild specsでmapが使えるようになった
```erlang
-spec Module:init(Args) -> Result when
    Args :: term(),
    Result :: {ok,{SupFlags,[ChildSpec]}} | ignore,
    SupFlags :: sup_flags(),
    ChildSpec :: child_spec().
```

```erlang
-type sup_flags() :: #{strategy => strategy(),         % optional(default: one_for_one)
                       intensity => non_neg_integer(), % optional(default: 1)
                       period => pos_integer()}        % optional(default: 5)
                    | {RestartStrategy :: strategy(),
                       Intensity :: non_neg_integer(),
                       Period :: pos_integer()}
```

```erlang
-type child_spec() = #{id => child_id(),       % mandatory
                       start => mfargs(),      % mandatory
                       restart => restart(),   % optional(default: permanent)
                       shutdown => shutdown(), % optional(default: 5000 if worker, infinity if supervisor)
                       type => worker(),       % optional(default: worker)
                       modules => modules()}   % optional(default: mfargs()のM)
                    | {Id :: child_id(),
                       StartFunc :: mfargs(),
                       Restart :: restart(),
                       Shutdown :: shutdown(),
                       Type :: worker(),
                       Modules :: modules()}
```

## stdlib: etsの新機能
### `ets:take/2`
http://www.erlang.org/doc/man/ets.html#take-2

`ets:delete/2` と同じように要素を削除する。
違いは **削除したオブジェクトを返す** ところ

```erlang
-spec delete(Tab, Key) -> true when
      Tab :: ets:tab(),
      Key :: term().
      
-spec take(Tab, Key) -> [Object] when
      Tab :: ets:tab(),
      Key :: term(),
      Object :: tuple().
```

### `ets:update_counter/4`
http://www.erlang.org/doc/man/ets.html#update_counter-4
引数としてデフォルトオブジェクトを使う（この辺り全然使っていないので、そもそもこの関数が何なのか、何が変わったのか…；）