# 機能設計書 36-コード引用（Quotations）

## 概要

本ドキュメントは、F#コアライブラリにおけるコード引用（Quotations）機能の機能設計を記述する。Quotations機能はF#コードを抽象構文木（AST）として表現するメタプログラミング機能を提供し、コンパイル時にF#コードをデータとして操作することを可能にする。

### 本機能の処理概要

**業務上の目的・背景**：従来のプログラミングでは、コード自体を実行時に検査・変換することは困難であった。F# Quotations機能はコードを引用（quote）してデータ構造として表現することで、LINQプロバイダ、DSL（ドメイン固有言語）の実装、コード生成、コード分析、式の最適化などの高度なメタプログラミングを可能にする。型付き引用（typed quotation）と生引用（raw quotation）の両方をサポートし、型安全性と柔軟性のバランスを提供する。

**機能の利用シーン**：SQL/NoSQLクエリのLINQプロバイダ実装、GPU計算用コードの変換（FParsec等）、コンパイル時コード生成、テストフレームワークでの式の検査、教育目的でのF#コード構造の可視化など。

**主要な処理内容**：
1. Expr型による式の抽象構文木表現
2. Var型による変数の表現
3. Patternsモジュールによる式の分解（アクティブパターン）
4. DerivedPatternsモジュールによる派生パターン
5. ExprShapeモジュールによる式形状の汎用操作
6. 式の構築関数（Expr.Value、Expr.Var、Expr.Lambda等）

**関連システム・外部連携**：F#コンパイラと連携し、引用構文（<@ @>および<@@ @@>）をサポート。System.Reflection APIと連携して型情報を取得。

**権限による制御**：本機能はライブラリ機能であり、権限による制御は行わない。

## 関連画面

該当なし（コアライブラリ機能であり、画面は持たない）

## 機能種別

メタプログラミング / コード変換 / AST操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| expr | Expr / Expr<'T> | Yes | 操作対象の式引用 | - |
| var | Var | No | 変数を表すオブジェクト | - |
| methodInfo | MethodInfo | No | メソッド情報 | - |
| propertyInfo | PropertyInfo | No | プロパティ情報 | - |
| unionCaseInfo | UnionCaseInfo | No | 判別共用体ケース情報 | - |

### 入力データソース

F#コンパイラによる引用構文の解析結果、またはExpr型のファクトリメソッドによる構築。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 結果 | Expr / Expr<'T> / Type / Var / MethodInfo / PropertyInfo | 式の構築結果または分解結果 |

### 出力先

関数の戻り値としてプログラムに返却。

## 処理フロー

### 処理シーケンス

```
1. 式の引用または構築
   └─ <@ expr @>（型付き）または <@@ expr @@>（生）
   └─ Expr.Value、Expr.Call等のファクトリメソッド
2. 式の分解・検査
   └─ Patternsモジュールのアクティブパターンでパターンマッチ
3. 式の変換・操作
   └─ ExprShapeで汎用変換
4. 結果の利用
   └─ コード生成、クエリ構築、最適化等
```

### フローチャート

```mermaid
flowchart TD
    A[F#コードを引用] --> B{引用種別}
    B -->|型付き<@ @>| C[Expr<'T>を生成]
    B -->|生<@@ @@>| D[Exprを生成]
    C --> E[式を分解]
    D --> E
    E --> F{パターンマッチ}
    F -->|Call| G[メソッド呼び出し情報を取得]
    F -->|Lambda| H[変数と本体を取得]
    F -->|Value| I[値と型を取得]
    G --> J[変換/利用]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-1 | 型保持 | 型付き引用は戻り値の型情報を保持する | <@ @>使用時 |
| BR-36-2 | 変数スコープ | Var型はスタンプで一意識別される | 式内の変数参照時 |
| BR-36-3 | 等価性 | ValueOp比較時、ValueWithNameはValueと等価として扱う | 式の等価性判定時 |
| BR-36-4 | Witness情報 | CallWithWitnessesパターンはCallパターンとして分解可能 | メソッド呼び出し分解時 |

### 計算ロジック

- 式の等価性判定は構造的等価性に基づく
- Varの比較はスタンプ値とname、型のメタデータトークンを使用

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

該当なし（メモリ上のデータ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentException | 実行時例外 | 無効なメソッド/プロパティ情報を指定した場合 | 正しいリフレクション情報を使用 |
| NotSupportedException | 実行時例外 | サポートされていない式構造を処理しようとした場合 | サポートされるパターンを確認 |

### リトライ仕様

該当なし（単純な同期操作のため）

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

該当なし（メモリ上の操作のみ）

## パフォーマンス要件

- 式の構築・分解はO(1)〜O(n)（式の複雑さに依存）
- Var.Globalは辞書でキャッシュされグローバル変数を効率的に再利用

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

- 引用された式はデータとして扱われ、自動的に実行されることはない
- 式の評価（eval）を行う場合は信頼できるソースからの式のみを処理すること

## 備考

- F# Quotationsは.NETのSystem.Linq.Expressions.Expressionとは異なるが、相互変換ライブラリが存在する
- 引用内ではすべてのF#構文がサポートされるわけではない（制限あり）
- Witness情報（F# 5.0以降）により、ジェネリック関数呼び出しの型クラス情報を保持可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | quotations.fs | `src/FSharp.Core/quotations.fs` | Var型の定義（98-175行目） |
| 1-2 | quotations.fs | `src/FSharp.Core/quotations.fs` | Tree/ExprConstInfo判別共用体（177-227行目） |
| 1-3 | quotations.fs | `src/FSharp.Core/quotations.fs` | Expr型の定義（228-448行目） |

**読解のコツ**:
- `Var`型は変数を表し、Name、Type、IsMutable、Stampを持つ
- `Tree`型は式の内部表現で、CombTerm（複合式）、VarTerm（変数）、LambdaTerm（ラムダ）、HoleTerm（穴）の4種類
- `ExprConstInfo`型は式の操作種別（AppOp、IfThenElseOp、LetOp等）を表す
- `Expr`型はTreeと属性リストをラップする公開型

#### Step 2: Patternsモジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | quotations.fs | `src/FSharp.Core/quotations.fs` | Patternsモジュール（450-900行目） |

**主要処理フロー**:
1. **545-560行目**: `Var`アクティブパターン - 変数式の分解
2. **551-555行目**: `Application`アクティブパターン - 関数適用の分解
3. **557-561行目**: `Lambda`アクティブパターン - ラムダ式の分解
4. **753-791行目**: `Call`アクティブパターン - メソッド呼び出しの分解
5. **773-790行目**: `CallWithWitnesses`アクティブパターン - Witness付きメソッド呼び出し

#### Step 3: 式の構築関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | quotations.fs | `src/FSharp.Core/quotations.fs` | 構築関数群（940-1500行目付近） |

**主要処理フロー**:
- `Expr.Value`: リテラル値の式を構築
- `Expr.Var`: 変数参照の式を構築
- `Expr.Lambda`: ラムダ式を構築
- `Expr.Call`: メソッド呼び出しの式を構築
- `Expr.Let`: let束縛の式を構築

#### Step 4: ExprShapeモジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | quotations.fs | `src/FSharp.Core/quotations.fs` | ExprShapeモジュール |

**主要処理フロー**:
- `ShapeVar`: 変数式
- `ShapeLambda`: ラムダ式
- `ShapeCombination`: その他の複合式

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

```
ユーザーコード
    │
    ├─ <@ fun x -> x + 1 @>
    │      └─ F#コンパイラ
    │             └─ Expr<int -> int>を生成
    │                    └─ Tree = LambdaTerm(v, CombTerm(StaticMethodCallOp, ...))
    │
    ├─ Patterns.Lambda expr
    │      └─ パターンマッチング
    │             └─ (E x) -> match x with LambdaTerm(a, b) -> Some(a, b)
    │
    ├─ Expr.Call(methodInfo, args)
    │      └─ チェック処理
    │             └─ mkFEN(StaticMethodCallOp(methodInfo), args)
    │
    └─ ExprShape.ShapeCombination(shape, args)
           └─ 式の汎用分解
                  └─ (op, subexprs)のタプルとして返却
```

### データフロー図

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

F#コード ─────────────▶ F#コンパイラ ──────────────────▶ Expr<'T>
<@ ... @>                     │
                              └──▶ AST構築 → Tree型に格納

Expr<'T> ─────────────▶ Patterns.xxx ──────────────────▶ 分解結果
                              │                              (Option型)
                              └──▶ パターンマッチでTree分解

分解結果 ─────────────▶ 変換ロジック ──────────────────▶ 変換後Expr
                              │
                              └──▶ Expr.xxxで再構築
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| quotations.fs | `src/FSharp.Core/quotations.fs` | ソース | Quotations機能の実装 |
| quotations.fsi | `src/FSharp.Core/quotations.fsi` | シグネチャ | Quotations機能のシグネチャ定義 |
