見出し画像

関数型プログラミング事始め (9) Lispは関数型

関数型プログラミングがはじめての方へ贈る入門の書
前節:遅延評価の苦難 次節:Lispは関数型(続)
参考書:
・五味 弘「はじめてのLisp関数型プログラミング」技術評論社(2016)
・大山口 通夫、五味 弘「プログラミング言語論」コロナ社(2008)
・五味 弘「関数型プログラミングと数学(ITと数学)」技術評論社(2021)

Lispは関数型プログラミング言語なのでしょうか。今回から始まるLisp超入門ですが、まずはLispの関数型言語としての概観を見ていくことにします。Lispは関数型言語の元祖ですが、洗練された関数型言語のライブラリはありません(きっぱり)。これらは手作りする必要がありますが、関数型の元祖、アセンブラと呼ばれています。

2章 Lisp超入門 - 関数型プログラミングのための

この章では関数型プログラミングを実装する言語として、Lispを紹介します。ただしLispの細かい言語仕様までは踏み込まずに、関数型プログラミングを実装するための最小限の超入門を紹介します。

2.1 Lispは関数型プログラミング言語

Lispの超入門の紹介の前に、Lispが関数型プログラミング言語としての機能があるかどうかを見ていくことにします。果たしてLispは関数型プログラミング言語なのでしょうか。

(1) 副作用

関数型プログラミングでは副作用はありません。あってがならないものです。純粋関数型と呼ばれるものでは厳禁です。

Lispは副作用は・・・あります。現在のLispには普通にあります。しかし古(いにしえ)のLispの思想にはありませんでした。純粋なラムダ計算を実行するための言語として生まれたLispには副作用はありません。

しかし副作用はプログラミング的に効率面で有効であり、他の言語では副作用を積極的に利用しています。そもそもストアードプログラム方式(プログラム内蔵式)のフォン・ノイマン型コンピュータでは副作用こそがプログラミングです。

という背景(言い訳)の下に、Lispも副作用の機能を取り入れ、「進歩」してきました。例えば、prog という手続き型プログラム構文を取り入れることにしました。これでもう完全に手続き型プログラミングができます。

もちろん現在のLispでも副作用の機能を使わなければ、副作用は生じません。ただしこれは他の言語にも同じように言えることです。

しかしLispはその生まれたときの背景からもわかるように副作用は必要悪として、ただ効率のためにだけ、注意深く使うように、躾けられていますから、安心してください。清く正しいLispには副作用はありません。たぶん。

(2) イミュータブルデータ

副作用を生じさせないためにはイミュータブル(不変)データの存在が重要です。Lispにはイミュータブルデータとして、リストがあります。Lispの名称はリスト処理(List Processing)から来ていて、リストはLispの基本中の基本です。このためLispはイミュータブルデータのリストでプログラミングするのが当たり前です。

このリストはデータを変更するときも追加型で実装されるので副作用は生じません。これについては、後述のLisp超入門のリスト操作で紹介します。

しかしLispにはリストに対しても破壊的操作ができる関数が用意されています。これは効率のために用意されていますが、これを使用するとリストでも副作用が生じます。これについても後述します。

またLispにはリスト以外にも配列や文字列など一般の言語にあるデータ型が用意されています。これらのデータは副作用が生じます。なおこれらのデータを使うときでも副作用が生じないようにする方法は後述します。

このようにイミュータブルデータとしてリストを清く正しく使えば、大丈夫です。たぶん。

(3) 再帰プログラミング

関数型プログラミングの構造は再帰です。Lispも再帰プログラミングが基本で、繰り返し構造は・・・あります。これも古のLispの思想にはありませんでしたが、やはり効率のために最初は prog 関連が導入され、その後、普通の for 文などが導入されました。

しかしあくまでもLispの基本構造は再帰です。これは変数宣言がないため。関数呼び出しの作成コストが小さく、気楽に再帰プログラミングの関数呼び出しができることがあります。

しかし再帰プログラミングは実装で、スタック操作が多発しますので、スタック操作を使わない繰り返し文の方が効率が良くなります。このため、上記にあるようにLispにも繰り返し文が導入されました。

このように再帰プログラミングで実装すれば、副作用の危険性も減少し、関数型プログラミングができます。たぶん。

(次回予告) (4) ラムダ、(5) 高階関数、(6) 遅延評価、(7) その他

次回は今回の続きとして、(4) ラムダ、(5) 高階関数、(6) 遅延評価、(7) その他の関数型プログラミングの機能からLispを見ていくことにします。

参考:プログラミング言語はどれがお得?(前編)|五味弘 (note.com)
参考:プログラミング言語はどれがお得?(後編)|五味弘 (note.com)

いいなと思ったら応援しよう!

五味弘
よろしければサポートをお願いします!