関数型言語(1)

人工知能技術 機械学習技術 デジタルトランスフォーメーション Clojure LISP Javascript プログラミング技術 ICT技術 プログラミング技術概要 本ブログのナビ
関数型言語(1)

前回、機械に直結した言語から、自然言語に近い高級言語へ進化し、さらに生産性の向上の方向性に向かって構造化言語からオブジェクト指向言語(OOP)へ進化するまでを述べた。今回はOOPとは異なった生産性向上のアプローチである「関数型言語」について述べてみる。

関数型言語の「関数」とは何なのかを説明する為、まず数学での関数を「純粋関数」と定義する。この純粋関数の特徴としては、下図に示すように入力を入れるとそれに対応した一意の出力が得られるというものになる。これは関数を数式y=f(x)で表し、入力として特定の値xが入れられればそれに対応したただ一つの値yが返ってくるものと言い換える事ができる。この性質は「参照透過性(referential transparency)」と呼ばれ、この参照透過性を担保するための性質として「副作用が無い」と言う言葉が使われる。

副作用とは、関数の本来の作用である値を入力したら値を返す以外の作用があることを言い、例えば変数の値を帰る為の破壊的代入文(y=ax+bとしたときaとb(内部状態)がある時点で変わること)であったり、配列の要素を破壊的(元の値がなくなってしまう)に変えたり、ファイルに書き込んだり、データベースに値を入れたり、画像を表示したりするもので、一般的なプログラミング言語の中では多く使われている機能となる。つまり副作用とは以下の図のように、何らかの関数を考えた時にその関数の内部状態が変化してしまう事を言う。

はじめてのLISP関数型プログラミングより

この状態を持つと言うものは、例えばチューリングマシンでのテープへの副作用での動作や、ノイマン型のコンピューターのプログラムとデータをメモリに格納して(副作用を起こして)動作させる形態等コンピューター技術の基本となる機能であると言える。

このように副作用はプログラミングにとっても省くことのできない必須の機能ではあるが、それらを不必要に多用すると、プログラムの中に制御できないデータの変化を生じてしまい深刻なバグの要因の一つとなるという負の側面を持つ。この副作用のコントロールを行う事がプログラミングの生産性を上げる為の重要な要因となる為、例えばOOPではクラスの中のローカル変数とグローバル変数をうまく設計することで、副作用のコントロールを行っている。

このOOPでアプローチでは、モジュールを有効に再利用する為に、何を持ってそれを区別したかという設計者の意図をそのクラスと共に残しておかなければならず、複雑な構成のプログミングではそれらの記録や確認の作業に手間がかかると共に、誤った意図が伝わる可能性も生じてバグが生成される要因ともなる。

これらを解決する為に、オブジェクト思考型では以下のようにデータ構造にそれぞれ関数がある形であったのを

clojureの世界観*1より

下図に示すような、「10種類のデータ構造にそれぞれを扱う10個の関数があるよりも、ひとつのデータ構造を扱う100個の関数がある方が良い (It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures)」と言う形とすることが関数型言語の根本的な思想となる。

Clojureの世界観*1より

このようなシンプルな構造とすることで、あたかも以下に示すようなレゴブロックでつくるようにプログラミングができることになる。下図ははRich Hickeyによる「simple made easy」からの抜粋である。この図で左上の城は毛糸細工で作ったのもの、右下はレゴブロックで作ったものを示し、毛糸細工でつくるものがOOPでのプログラミングのアナロジー、レゴブロックで作る方が関数型言語のアナロジーとして紹介されている。

simple make easyより

ここで、毛糸細工のものでもレゴブロックのものでもモジュール構成として作ることは可能であるが、最小単位がオブジェクト(クラス)と関数で異なり、関数の方が「Ease to undersatnd」「Ease to change」「Flexibility(Policy、location,etc)」でオブジェクトのものと比べて優れている為、simpleでeasyなプログラミングが可能であると述べられている。

今回は関数型言語とOOPの違いに焦点を当てて述べた。次回は、関数型言語の歴史の観点からそれらの特徴について述べてみたいと思う。

参照: 1) Clojureの世界観

コメント

  1. […] また、特徴の一つとして関数型言語であるというものがある。これはpyhtonやjavascript等の通常の言語が手続きを書き並べていく言語であるのに対して、関数という機能ブロックで全てのプログラムを構成するというプログラミング言語の歴史の中では最新のトレンドに部類されるものとなる。 […]

  2. […] JavaScriptを書きやすくしたTypeScriptを除くと、その他の人気のある言語はどれも関数型言語の機能を利用しているのが興味深い。またそれぞれの言語は、プログラミング言語を語る上で重要な「型」の扱いで特徴を出しており、後日それらに関しては整理したいと思う。 […]

  3. […] 前回に引き続き関数型言語について述べる。今回はその歴史について参照図書としては「はじめてのLISP関数型プログラミング ラムダ計算からリファクタリングまで」から。関数型言語(LISP系)の歴史を以下に示す。 […]

  4. […] Clojureの特徴の一つとして関数型言語であるというものがある。これはpythonやjavascript等の通常の言語が手続きを書き並べていく言語であるのに対して、関数という機能ブロックで全ての […]

  5. […] 関数型言語(1) 関数について […]

  6. […] Clojureの特徴の一つとして関数型言語であるというものがある。これはpythonやjavascript等の通常の言語が手続きを書き並べていく言語であるのに対して、関数という機能ブロックで全ての […]

タイトルとURLをコピーしました