Kotlin イン・アクション「開いたレンジ」の詳細を探る

【移行のお知らせ】[プライバシー上の懸念](https://blog.qiita.com/about-user-page-renewal-20200326/)により、Qiitaアカウントの削除を検討しています。
各投稿は個人blog( https://gateau.hatenablog.com/archive/category/Qiita )に移行しました。
今後も参照される方は、ブックマークなど移行をお願い致します。

---

Kotlin イン・アクションの第7章「7.3.2 inの規約」の中で **開いたレンジ（open range）** という言葉が出てきます。（P.242 1行目）
> **開いたレンジ**とは、終端を含まないレンジを指します。例えば、10..20という記法を使い、通常の（閉じた）レンジを作る場合、このレンジには20も含む10から20の全ての数値が含まれます。10 until 20という開いたレンジには、10から19までが含まれますが、20は含まれません。

聞いたことがない表現なので、Kotlin用語なのか質問したり調べた結果をまとめます。

## Kotlin イン・アクション読書会で質問
[こちらのtweet](https://twitter.com/mhidaka/status/1019796425155072000)で告知されている読書会で質問してみました。
<img width="616" alt="スクリーンショット 2018-07-21 14.34.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/36199/32b5b9eb-5c76-4946-ab45-c9a6d48cbc69.png">

回答は「**開いた・閉じたという表現は数学的な用語**」とのこと。
またハッシュタグ [#merstudy](https://twitter.com/search?f=tweets&vertical=default&q=%23merstudy&src=typd) を追ったところ 「[開区間/閉区間に対応してるのかな](https://twitter.com/cor0suke_k/status/1019825056375959552)」というtweetが出てきて、調べてみたらその通りでした。集合知有り難し。

## 開区間・閉区間

### 定義

[金沢工業大学さんのサイト](http://w3e.kanazawa-it.ac.jp/math/category/other/syuugou/henkan-tex.cgi?target=/math/category/other/syuugou/kukann.html) から定義を引用します。
> 区間とは ，数直線上のある区切りの間の数（実数）の集合のことである．区切りの数を含むか含まないかで区間の呼び方が異なり，開区間，閉区間，半開区間がある．
> 区切りを含む場合を閉区間という． 
> 区切りを含まない場合を開区間という
> 片方の区切りを含み，他方の区切りを含まない場合を半開区間という

自分の感覚では「開いた」の方が範囲が広そうなのに狭いのが不思議だったのですが、図を見ると区切りの丸が○の方が開いている（空いている、含まない）で、●の方が閉じている（埋まっている、含む）ので、納得しました。もう間違えない。

### untilで開いてるのは片方だけ
jetbrains社のKotlinブログに [What’s new in Standard Library M13 and M14](https://blog.jetbrains.com/kotlin/2015/09/whats-new-in-standard-library-m13-and-m14/) という記事があり、ここにもレンジの説明がありました。
そこでは **right-open ranges** とあり、「右側（数字の大きい方）が開いている」と明言してありました。

> Constructing open ranges
> There was a common request to introduce right-open ranges in Kotlin. We have examined use-cases and found that most of them are involving integer ranges. In case of integers an opened at the end range can be represented with a closed range, whose end value is one less than the corresponding open range’s end.
To create such ranges you can use newly introduced until function. It returns closed range with values up to the specified end but not including it, so that:
> 0 until 20 == 0..19

[wikipediaのintervalのページ](https://en.wikipedia.org/wiki/Interval_(mathematics)#Classification_of_intervals)にある、「Left-closed, right-open」という表現とも一致しています。納得。

## Kotlin 用語なのか？
「レンジ」がKotlinのクラス名なので、ある意味Kotlin用語かもしれません。
数学の「区間」は英語にすると上記wikipediaの通り「interval」です。
他のプログラミング言語でも「レンジ」クラスやメソッドが出てきたら「開いたレンジ」と言えるものはありそうです。

## 他の言語でのright-open ranges
最後の値を含む・含まない両方を表現できる言語はこの辺りがあるようです。他にもありそうですがこれぐらいで。
#### Java8
```java
IntStream.rangeClosed(10, 15)  // 10,11,12,13,14,15
IntStream.range(10, 15)        // 10,11,12,13,14
```
#### Ruby
```ruby
10..15    # 10,11,12,13,14,15
10...15   # 10,11,12,13,14
```
#### Swift
```swift
10...15   // 10,11,12,13,14,15
10..<15   // 10,11,12,13,14
```
#### Scala
```scala
10 to 15      // 10,11,12,13,14,15
10 until 15   // 10,11,12,13,14
```

## まとめ
- 開いた/閉じた は数学の区間に該当する用語である
- right-openな区間を表したい需要があり、Kotlin以外でも同様の表現が出来る言語がある

### 参考ドキュメント
n..mやrange(n, m)など範囲型やrangeと呼ばれるものでmは含まれるかどうかを調べてみた https://qiita.com/aimof/items/f25af524b3866c5706aa