# 機能設計書 133-Option型

## 概要

本ドキュメントは、Julia の `Some` / `nothing` / `isnothing` / `something` による値の有無を表す型（Option型パターン）について、その設計・処理仕様を記述するものである。

### 本機能の処理概要

`Some{T}` 型と `Nothing` 型を組み合わせて、値の有無を型安全に表現する機能である。`Some(x)` は値 `x` が明示的に存在することを示し、`nothing` は値が存在しないことを示す。特に、`nothing` 自体を有効な値として扱いたい場合（`Some(nothing)` と `nothing` を区別）に必須となるパターンである。

**業務上の目的・背景**：関数の戻り値として「値が見つからなかった」状態を表現する必要がある場面で、`nothing` を利用する。しかし `nothing` 自体が有効な値である場合に `Some` ラッパーで区別する。辞書の `get` 関数や検索関数の戻り値など、広く利用されるパターンである。

**機能の利用シーン**：辞書検索のデフォルト値指定、オプショナルパラメータのデフォルト値、関数の戻り値としての「値なし」表現、チェーン式のフォールバック処理（`something(f1(), f2(), f3())`）など。

**主要な処理内容**：
1. `Some{T}` ラッパー型の提供（値の存在を明示）
2. `nothing` シングルトン値の提供（値の不在を表現）
3. `isnothing(x)` による nothing 判定
4. `something(x...)` による最初の非nothing値の取得
5. `@something(x...)` マクロによる短絡評価版
6. `notnothing(x)` による nothing チェック付き値取得
7. 型昇格規則による `Union{T, Nothing}` の自動導出

**関連システム・外部連携**：Julia の型昇格システム、Missing 型（相補的な関係）、Dict の get 関数などと連携する。

**権限による制御**：特に権限による制御はない。

## 関連画面

本機能は特定の画面との紐付けはない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | REPLやスクリプトから nothing/Some を使った値の有無表現に利用される |

## 機能種別

データ型 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | Any | Yes（Some） | ラップする値 | - |
| x | Any | Yes（isnothing） | nothing かどうか判定する値 | - |
| x... | Any | Yes（something） | 最初の非nothing値を返す可変長引数 | 1つ以上の引数が必要 |

### 入力データソース

Julia のコード内での直接利用。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Some(x) | Some{T} | 値 x を Some でラップした結果 |
| isnothing結果 | Bool | x === nothing の判定結果 |
| something結果 | T | 最初の非nothing値。Some はアンラップされる |
| notnothing結果 | T | nothing でなければ x、nothing なら ArgumentError |

### 出力先

呼び出し元への戻り値。

## 処理フロー

### 処理シーケンス

```
1. Some{T} 型の定義
   └─ フィールド value::T を持つ構造体
2. nonnothingtype の定義
   └─ Union 型から Nothing を除去
3. 型昇格規則の定義
   └─ promote_rule(Nothing, S) = Union{S, Nothing}
4. 変換規則の定義
   └─ convert(Union{T, Nothing}, x) の処理
5. something 関数の定義
   └─ 再帰的に最初の非nothing値を探索。Some はアンラップ
6. @something マクロの定義
   └─ 短絡評価版の something
7. isnothing / notnothing の定義
   └─ nothing 判定ユーティリティ
8. == / isequal / hash の定義
   └─ Some 値の比較・ハッシュ
```

### フローチャート

```mermaid
flowchart TD
    A["something(x1, x2, ...)"] --> B{"x1 は nothing?"}
    B -->|Yes| C{"x2 は nothing?"}
    B -->|"No (Some(v)の場合)"| D["v を返す (アンラップ)"]
    B -->|"No (通常値)"| E["x1 を返す"]
    C -->|Yes| F["... 残りの引数を再帰的にチェック"]
    C -->|No| G["x2 を返す"]
    F --> H{"全て nothing?"}
    H -->|Yes| I["ArgumentError: No value arguments present"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-133-01 | Some ラッピング | `Some(T)` where T is Type は `Some{Type{T}}(T)` を返す（型をラップ可能） | Some に Type を渡した場合 |
| BR-133-02 | something のアンラップ | `something(Some(x))` は `x.value` を返す（Some をアンラップ） | Some 値が見つかった場合 |
| BR-133-03 | something の例外 | 全引数が nothing の場合は ArgumentError をスロー | something に nothing のみが渡された場合 |
| BR-133-04 | isnothing 判定 | `isnothing(x)` は `x === nothing` と同等 | 常時 |
| BR-133-05 | notnothing 例外 | `notnothing(nothing)` は ArgumentError をスロー | nothing が渡された場合 |
| BR-133-06 | 型昇格 | `promote_rule(Nothing, S)` は `Union{S, Nothing}` を返す | 型昇格時 |
| BR-133-07 | Some の等価性 | `Some(a) == Some(b)` は `a == b` と同等 | Some 同士の比較 |

### 計算ロジック

**something の再帰処理**（99-102行目）:
- `something()` -> ArgumentError（引数なし）
- `something(nothing, y...)` -> `something(y...)`（nothing をスキップ）
- `something(Some(x), y...)` -> `x.value`（Some をアンラップ）
- `something(x, y...)` -> `x`（通常値はそのまま返す）

**hash の計算**（172行目）:
- `hash(s::Some, h::UInt) = hash(s.value, hash_some_seed + h)` -- seed を加算してラップされた値のハッシュを計算

## データベース操作仕様

本機能はデータベース操作を行わない。

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | `something()` に引数なし、または全て nothing | 少なくとも1つの非nothing値を渡すか、デフォルト値としてSome(default)を末尾に追加 |
| - | ArgumentError | `notnothing(nothing)` | nothing でない値を渡す |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- `Nothing` はシングルトン型でメモリオーバーヘッドなし
- `Some{T}` は1フィールドの構造体であり、コンパイラによるインライン化が期待される
- `isnothing(x)` は `===` 比較に展開され、最小コスト
- `@something` マクロは短絡評価により不要な式の評価を回避

## セキュリティ考慮事項

特筆すべきセキュリティ考慮事項はない。

## 備考

- `Nothing` 型は Core で定義されている
- `nothing` は `Nothing()` のシングルトンインスタンス
- `Some` と `Missing` は相補的：`Some` は「値の存在」、`Missing` は「値の欠損」を表す
- `@something` マクロは Julia 1.7 以降で利用可能
- `hash_some_seed` は UInt64/UInt32 に応じて異なる定数値を使用（171行目）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | some.jl | `base/some.jl` | **11-13行目**: `struct Some{T}` -- value フィールドを1つ持つパラメトリック構造体 |
| 1-2 | some.jl | `base/some.jl` | **15行目**: `Some(::Type{T})` -- Type に対する特殊コンストラクタ。`Some{Type{T}}(T)` を返す |
| 1-3 | some.jl | `base/some.jl` | **17行目**: `nonnothingtype` -- typesplit による Union 型からの Nothing 除去 |

**読解のコツ**: `Some{T}` はいわゆる Option/Maybe パターンの Julia 実装。`Union{Some{T}, Nothing}` で「T型の値があるかないか」を表現する。

#### Step 2: 型昇格と変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | some.jl | `base/some.jl` | **18行目**: `promote_rule(Nothing, S) = Union{S, Nothing}` |
| 2-2 | some.jl | `base/some.jl` | **19-25行目**: `>:Nothing` 型に対する promote_rule |
| 2-3 | some.jl | `base/some.jl` | **34-37行目**: convert メソッド群 |

**主要処理フロー**:
- **34行目**: `convert(T>:Nothing, x::T)` -- 既に正しい型ならそのまま返す
- **35行目**: `convert(T>:Nothing, x)` -- nonnothingtype_checked で Nothing を除いた型に変換
- **36-37行目**: `convert(Some{T}, x::Some)` -- Some 同士の変換

#### Step 3: something 関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | some.jl | `base/some.jl` | **97-102行目**: `something` 関数の4つのメソッド |

**主要処理フロー**:
- **99行目**: `something()` -- 引数なしで ArgumentError
- **100行目**: `something(x::Nothing, y...)` -- nothing をスキップして再帰
- **101行目**: `something(x::Some, y...)` -- Some をアンラップして value を返す
- **102行目**: `something(x::Any, y...)` -- 通常値はそのまま返す

#### Step 4: @something マクロを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | some.jl | `base/some.jl` | **138-167行目**: `@something` マクロ -- 短絡評価版 |

**読解のコツ**: マクロは引数をリバースして内側からネストされた if/else 式を構築する。各引数に対して `isnothing` チェックを行い、nothing でなければ `something()` でアンラップして返す。

#### Step 5: ユーティリティ関数と比較・ハッシュを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | some.jl | `base/some.jl` | **54-55行目**: `notnothing` 関数 |
| 5-2 | some.jl | `base/some.jl` | **67行目**: `isnothing` 関数 |
| 5-3 | some.jl | `base/some.jl` | **169-172行目**: `==` / `isequal` / `hash` の Some 特殊化 |

### プログラム呼び出し階層図

```
something(x1, x2, x3)
    |
    +-- x1::Nothing の場合
    |       └── something(x2, x3)  # 再帰
    |
    +-- x1::Some{T} の場合
    |       └── x1.value を返す
    |
    +-- x1::Any の場合
            └── x1 を返す

@something(x1, x2, x3)
    |
    +-- val_1 = x1
    |   +-- !isnothing(val_1) ?
    |       +-- Yes: something(val_1)  # アンラップ
    |       +-- No:
    |           +-- val_2 = x2
    |               +-- !isnothing(val_2) ?
    |                   +-- Yes: something(val_2)
    |                   +-- No:
    |                       +-- val_3 = x3
    |                           +-- ...
    |                           +-- something(nothing)  # 最終: ArgumentError
```

### データフロー図

```
[入力]                        [処理]                       [出力]

Some(42)                 --> Some{Int64} 構築          --> Some{Int64}(42)
something(nothing, 1)    --> nothing スキップ          --> 1
something(Some(nothing)) --> Some アンラップ           --> nothing
isnothing(nothing)       --> === nothing 判定          --> true
isnothing(42)            --> === nothing 判定          --> false
notnothing(nothing)      --> チェック                  --> ArgumentError
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| some.jl | `base/some.jl` | ソース | Some型、something、isnothing、notnothing、@something の全実装 |
| essentials.jl | `base/essentials.jl` | ソース | Nothing 型の定義（Core由来） |
| missing.jl | `base/missing.jl` | ソース | Missing型（相補的な型。coalesce は something の Missing 版） |
| promotion.jl | `base/promotion.jl` | ソース | promote_rule / promote_type の基盤 |
| test/some.jl | `test/some.jl` | テスト | Some/Nothing 機能の回帰テスト |
