🥕

再帰関数に対する苦手意識からの解放

2024/12/18に公開

みなさんは再帰関数お得意ですか?私は、長年、再帰関数に苦手意識を持っていましたが、現実世界の問い合わせ構造に繋げて理解したことで、急にその概念が腹落ちしました。

現実世界の問い合わせと再帰関数

例えば、あるレストランが常連の八百屋さんに次のような問い合わせをしました。「明日までに新鮮な人参100本が必要なんです。急で申し訳ないのですが、在庫があれば、単価を教えていただけますか?」。八百屋は事情を理解しましたが、残念ながら自店には在庫がありません。そのため、卸業者に「同じ条件での単価を教えてほしい」と依頼しました。しかし、卸業者にもストックがなく、農場にまで話が遡ります。農場には運良く在庫があり、「1本25円です」と回答しました。

call

この世界では、全員が原価の2倍のマージンを上乗せするルールがあるため、卸業者は「急な依頼ですが、1本50円で提供できます」と八百屋に伝えます。そして、八百屋はその情報を元に「今回は特別に手配できますが、1本100円になります」とレストランに回答しました。

return
このような仕組みが再帰関数の構造とよく似ています。

単なる伝言ゲームではない

再帰関数が現実世界の問い合わせと似ているのは、単なる伝言ゲームではない点です。コアとなる答えをそのまま渡すだけでなく、都度加工していくプロセスが含まれているからです。

先ほどのレストランの例では、農場が提示した"1本25円"という原価に対して、卸業者がマージンを上乗せして"1本50円"にし、さらに八百屋が"1本100円"として回答しています。この加工プロセスが、再帰関数の重要な特徴である「値の変換」に該当します。

また、ソフトウェア不具合の例では、技術者が提示する専門的な回答をベースに、営業やサポート担当がクライアントにわかりやすく翻訳したり、誤解を防ぐ表現に修正したりする工程があります。このように、情報をそのまま伝えるだけではなく、状況に応じて加工・変換する点が再帰関数の本質的な部分と言えます。

再帰関数の主要な要素

このように、先ほどのレストランの例は、再帰関数の主要な要素をすべて含んでいます。

1.終了条件: 問い合わせの最終点が決まっていること。
1.再帰呼び出し: 情報が足りない場合、再帰的に同じ関数を呼び出す。
1.値の変換: 答えを都度加工して戻す。

例えば、農場がストックを確認して単価を回答する部分が終了条件に該当します。問い合わせが八百屋から卸業者、さらに農場へと伝わる流れは再帰呼び出しそのものです。そして、回答にマージンを上乗せする過程が値の変換として表現されています。

再帰関数に苦手意識を持っていた理由

再帰関数の説明としてよくあるのは「n以下の正の数の総和を計算する」といったマスマティカルな例です。しかし、数学が得意ではない私にとって、こうした抽象的な説明は理解するのが難しく、目の前の問題を再帰の関係性に分解することに大変苦労しました。

しかし、現実世界の問い合わせフローをモデル化すると、再帰関数の実装時にも直感的に理解しやすくなります。例えば、問い合わせの流れや回答の加工といった要素が、コードの各部分と一致するため、よりリアルに再帰関数を捉えることができました。

現実的な例に繋げることで、初学者の方にも再帰関数の実装イメージを提供しやくできると思います。

Discussion