「モノイド的論理プログラミング(2) - エレファント・ビジュアライザー調査記録」の続きとして ChatGPT で分類してもらいました。
入力:
プログラミング言語によって、関数の引数を評価した後で渡す場合と関数の引数を評価せずにクロージャーのような形で渡す場合があります。関数の引数を評価せずに渡す場合、変数が変更可能でないならば一回だけ評価すれば良いし、変数が変更可能ならば毎回評価する必要があります。関数の引数の渡し方といつ何回評価するかを分類してください
結果:
関数の引数の渡し方と評価のタイミングについては、以下の3つの観点で分類できます。
1. 評価のタイミング
- 即時評価 (Eager Evaluation)
- 遅延評価 (Lazy Evaluation)
2. 評価の回数
- 一回だけ評価
- 毎回評価
3. 参照の性質
- 不変参照(Immutable Reference)
- 可変参照(Mutable Reference)
分類表
評価のタイミング 評価の回数 参照の性質 言語の例/実装方法 即時評価 一回だけ評価 不変参照 C, Java, Python 即時評価 一回だけ評価 可変参照 C++(参照渡し)、Java 遅延評価 一回だけ評価 不変参照 Haskell, OCamlの`lazy` 遅延評価 一回だけ評価 可変参照 不明(一般的には少ない) 遅延評価 毎回評価 不変参照 Scala(by-name パラメータ) 遅延評価 毎回評価 可変参照 Lisp系言語(特殊形式) 詳細な説明と例
1. 即時評価 (Eager Evaluation)
- 説明: 関数呼び出しの際にすべての引数を即座に評価し、値を渡す。
- 利点: 実装が簡単で予測可能。
- 例:
def eager_func(a, b): return a + b print(eager_func(1 + 2, 3 + 4)) # すべての式は関数呼び出しの前に評価される2. 遅延評価 (Lazy Evaluation)
- 説明: 引数は実際に使われるまで評価されない。
- 利点: 無駄な計算を省き、パフォーマンスが向上する場合がある。
- 例: Haskell
myFunction :: Int -> Int -> Int myFunction x y = x + 1 -- yは評価されない3. 一回だけ評価
- 説明: 引数が必要になったときに一度だけ評価され、その結果がキャッシュされる。
- 例: Haskell
myFunction :: Int -> Int -> Int myFunction x y = x + y main = print (myFunction 1 (expensiveComputation 10)) -- expensiveComputationは一度だけ評価4. 毎回評価
- 説明: 引数が使われるたびに再評価される。
- 例: Scala
def printValue(x: => Int): Unit = { println(x) println(x) } printValue({ println("Evaluating..."); 42 })出力:
Evaluating... 42 Evaluating... 425. 可変参照(Mutable Reference)
- 説明: 引数が関数内で変更可能である場合、評価のタイミングと回数に影響する。
- 例: C++
void modify(int& x) { x += 1; // xは参照で渡され、関数内で変更可能 } int main() { int a = 5; modify(a); std::cout << a; // 出力: 6 }設計上の注意
- 不変参照が保証される場合、引数を一度だけ評価することで効率的な遅延評価が可能。
- 可変参照を扱う場合は、引数が変更されるたびに再評価が必要なケースがあり、動作の予測が難しくなる。
- 遅延評価の利点を最大限に活用するには、必要に応じて評価回数を設計段階で考慮することが重要です。
どの戦略を採用するかは、言語の特性やアプリケーションの要求に依存します。
![[増補改訂]関数プログラミング実践入門 ──簡潔で、正しいコードを書くために WEB+DB PRESS plus [増補改訂]関数プログラミング実践入門 ──簡潔で、正しいコードを書くために WEB+DB PRESS plus](https://m.media-amazon.com/images/I/41qNdZiV1qL._SL500_.jpg)







