icon
icon

今注目されている!関数型プログラミングとは【初心者向け】

初心者向けに関数型プログラミングとは何か詳しく解説しています。企業でも採用し始めている関数型言語ですが、一体どんな特徴があり他の言語と比べてどんなメリット・デメリットがあるのか説明しています。代表的な関数型言語も覚えておきましょう。

テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日  調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名  調査手法:インターネット調査

この記事では、関数型プログラミングとは何なのか、解説しています。

関数型言語は、効率よく開発できる言語として採用している企業も増えてきています。言語の特徴やどんなメリットデメリットがあるのか理解しておきましょう。

 

 

田島悠介

今回は関数型プログラミングについて勉強してみよう。

大石ゆかり

田島メンター!関数型プログラミングというのは何ですか〜?

田島悠介

関数の組み合わせによってプログラムを構成していく手法を指して言うんだ。例を見ながら紹介していこう。

大石ゆかり

お願いします!

目次

1時間でできる無料体験!

 

関数型プログラミングとは

関数型プログラミングとは、解決しようとする問題に対し、その問題の性質を関数の組み合わせで記述するプログラミング手法です。

これに対し、命令型プログラミングでは、問題を解く手順をコンピュータが実行すべき命令の列として記述します。

言葉だけでは分かりづらいので、例を見ていきましょう。

 

種別(category)と価格(price)を持つ商品(Item)のリストから、食品(種別がFoodsのもの)の合計金額を計算するメソッドを考えます。

まずは、Javaで記述した場合の命令型プログラミングのサンプルです。

Javaのプログラム

public int totalFoodsPrice(List<Item> itemList) {
  int totalPrice = 0;
  for (int i = 0; i < itemList.size(); i++) {
    Item item = itemList.get(i);
    if (Objects.equals(item.getCategory(), "Foods")) {
      totalPrice += item.getPrice();
    }
  }
  return totalPrice;
}

この処理の中では、変数iは商品リストの何番目を処理しているか、変数totalPriceは現在計算が完了している合計金額がいくらになっているか、というプログラムの状態を表します。

変数iは、ループが行われるごとにi+という命令文によって、現在のiに1を足した値が代入されます。

変数totalPriceは、totalPrice += item.getPrice( )という命令文によって、ループ中の商品の価格を足した値が代入されます。

このように、プログラムの状態を表す変数の値を代入命令で変更していき、最終的に目的を達成することは命令型プログラミングの基本的な流れになります。

 

次に、Scalaを使用して同じ処理を関数型スタイルで実装した場合のサンプルです。

Scalaのプログラム

def totalFoodsPrice(itemList: List[Item]): Int = itemList match {
  case Nil => 0
  case Item("Foods", price) :: otherItems => price + totalFoodsPrice(otherItems)
  case _ :: otherItems => totalFoodsPrice(otherItems)
}

このメソッドは入力として商品リストを受け取り、先頭が食品であれば残りの商品リストの合計金額に価格を足し、そうでない場合は残りの商品リストの合計金額をそのまま返す、という内容になっています。

一見、馴染みが無い方には分かりづらくなったように思われるかもしれませんが、このメソッド内には変数の初期化や代入といった命令文が存在しません。現在は何番目の商品を扱っているか、現在の合計金額はいくらか、といった状態はここには現れないということです。

状態を変化させながらループさせるという手段の代わりに、すべての商品に対する繰り返し処理は同じメソッドを再帰的に呼び出すことで実現しています。

※ 再帰処理をすることが重要なのではなく、状態を扱わないということが重要で、実現方法は他にも存在します。

 

状態をプログラムの中で扱い、変化させていくことは、プログラムの動作を分かりづらくさせたり、テストやデバッグを困難にする原因となります。

これを避け、プログラムの状態を変化させない関数を作成し、これを組み合わせて(上記の例では再帰的に呼び出して)問題解決を行う手法が関数型プログラミングです。

ここで、変数の再代入や入出力などによってプログラムの状態が変化することを副作用と言い、副作用を持たない関数を純粋関数と呼びます。

関数型プログラミングの基本は、純粋関数の組み合わせでプログラムを作り上げることとなります。

 

田島悠介

関数型の基本的な特徴についてだね。

大石ゆかり

JavaとScalaを比較してみると、目的に対する手順が違っているのが分かりますね。

田島悠介

次に、関数型プログラミングにはどういったメリットやデメリットがあるのかについて見てみよう。

[PR] 無料で現役エンジニアから学べる

関数型プログラミングのメリット

プログラムの分かりやすさ

関数型プログラミングの最大のメリットは、プログラムが人間にとって分かりやすくなるという点です。

命令型で書かれたプログラムは、人間に対する分かりやすさよりコンピュータにとっての分かりやすさが優先されています。コンピュータにとって、実行中のプログラムの状態が明確であることは重要なポイントです。

しかし、人間が本来関心を持つのは実行中のプログラムの状態ではなく、プログラムに対する入力とその実行結果です。

関数型プログラミングでは、入力に対して必要な結果を導く関数を用意し、組み合わせていきます。関数の内容は実行中のプログラムの状態からは独立したものとなり、より人間の思考に近く、書く側にとっても読む側にとっても分かりやすいものとなります。

 

テストのしやすさ

関数型プログラミングでは、関数に対して同じ入力から等しい実行結果が得られるため、テストがしやすくなるというメリットもあります。

これは、正確には関数型プログラミングのメリットというよりは副作用を抑えるプログラムのメリットで、命令型プログラミングでも意識して設計すれば得られるメリットです。

実際、命令型プログラミングでもテストのしやすさを重視し、副作用に気を配っているという方も少なくないと思います。

ですが、関数型プログラミングでは純粋関数を宣言して組み合わせることが基本になるため、このメリットをより自然に受けることができます。

 

関数型プログラミングのデメリット

パフォーマンスチューニングが難しい

命令型プログラミングでは、1行ずつどういった命令をコンピュータが行なっているかが明確なので、比較的パフォーマンスチューニングが行いやすいと言えます。

これに対し、関数型プログラミングでは、コンピュータが実際に実行する1つ1つの命令を把握するのは難しく、命令型プログラミングほどチューニングは容易ではありません。また、無理にチューニングすることで、関数型としては不自然なコードになってしまう場合もあります。

 

誤解してはならないのは、関数型プログラミングでは実行速度が遅い、ということは決してなく、広く使われている関数型言語は多くの命令型言語と比べても遜色ない実行速度を備えています。ですが、CやC++、あるいはFORTRANが選ばれるような、限界までハードウェアの性能を引き出すことが必要な用途で関数型プログラミングを使用することは、現実的とは言えません。

もちろん、世の中の多くのソフトウェアはそこまでの性能は必要なく、開発効率やメンテナンス性の方が重要になります。このような多くの分野では、関数型プログラミングは有効な手段となります。

 

コラム

コスパとタイパ、両方結果的に良くなる良くなる学び方とは?

「スクールは高いし時間も縛られて効率が悪い」と考える方は多いと思います。
もちろん、時間も費用もかかることは間違いありません。
ただ 結果的に無駄な学びにお金も時間もかける方がリスクが高いという考えもあります。

コスパ・タイパ最適化の参考として、 テックアカデミー卒業生がスクールを選んだ理由 をご紹介します。

  • ・困ったときに、質問や相談できる相手がいるため挫折しなかった
  • ・プロとして必要なスキルのみを深く学べたので無駄がなかった
  • ・副業案件の提供と納品までのサポートがあったので目的を達成できた

安価・短期間で広く浅く学んでも意味がありません。 本当に自分の目的が達成できるか、それが重要です。
自分にどのスキルや学び方が合っているか、どんな学習方法かなど、お気軽に 無料相談 に参加してみませんか?

カウンセラー・現役のプロへ、何でも気軽に無料相談可能。 30分か60分お好きな時間が選べて、かつ3回まで すべて無料で ご利用できます。
無理な勧誘は一切ない ので、お気軽にご参加ください。

今なら相談した方限定の割引・参加特典付き! 無料相談はこちら

関数型言語とは

関数型言語とは、関数型プログラミングを行うことを推奨して設計されているプログラミング言語です。

誤解してはならない点として、

  • 関数型言語でなければ関数型プログラミングが行えない
  • 関数型言語では命令型のプログラミングを行うことができない

この2点は誤りです。

関数型プログラミングを実現すること自体は、多くのプログラミング言語で可能です。逆に、関数型言語と呼ばれる言語でも命令型のプログラミングを行うことができます。

ですが、一般に関数型言語と呼ばれる言語には、言語の設計段階から関数型プログラミングの実現を補助するための多くの言語機能が用意されており、それらを使って関数型プログラミングを行うことが前提となっています。「この言語機能があれば関数型言語である」という定義があるわけではありませんが、この特性によって関数型言語で作成した関数型プログラミングは非常にシンプルで自然なものとなります。

 

また、関数型言語にはさらに純粋関数型言語と非純粋関数型言語の2種類が存在します。

純粋関数型言語では、すべての式や関数が純粋関数のみで構成されます。一方で、実用性や既存言語との相互運用性を考慮し、副作用を持つ関数を許容する言語も多く存在し、これらは非純粋関数型言語と呼ばれます。

この2種類は、どちらかが優れているというものではなく、その言語が目指す方向性の違いによって異なっているものです。

 

主な関数型言語

Scala

オブジェクト指向言語と関数型言語の特性を併せ持つ、マルチパラダイムの関数型言語です。

2つの言語特性を1つの概念として統合することにより、小さなスクリプトから大きなシステムまで同じ概念で実現できるスケーラブルな言語仕様が特徴です。

Java仮想マシン(JVM)上で動作し、既存のJavaプログラムやJavaライブラリと容易に連携できることも特徴で、広く使われてきたJavaの資産を有効に活用することができます。

TwitterがScalaを大規模に採用しているほか、国内でもChatWorkやBacklogなどScalaへの移行事例が増えてきています。

Scala

 

Haskell

純粋関数型言語と言える言語です。

純粋関数型言語でありながら入出力のような副作用を伴う操作を実現するためにモナドという機能を持ち、その他にも多くの先進的なプログラミング機能を持っています。

その結果、言語の仕様に従うことで、「良い関数型プログラミング」となるような実装を行いやすくなっています。

Facebookにおけるスパムやマルウェア対策に使われているほか、国内ではTsuru Capital社が金融商品の高頻度取引システムで使用するなど、信頼性の求められる分野でも広く使用されています。

Haskell

 

Erlang

エリクソン社が自社用に開発し、のちにオープンソースとして公開した関数型言語です。

同時実効性の非常に高い電話交換アプリケーションの構築を目的として設計されたという経緯もあり、仮想マシン(Erlang VM)上で大量のプロセスを実行するための並行処理プログラミングをサポートする言語機能を持っています。

近年はLINEやWhatsAppのほか、League of Legendsというゲームのチャットシステムなど、主に大量のリクエストをリアルタイムで処理する分野で採用されています。

Erlang

 

以上、関数型プログラミングについて解説しました。

関数型言語を採用し始めている企業も増えていますが、どんな特徴を持った言語なのか知っておくと良いでしょう。

 

田島悠介

最後に、関数型言語をいくつか挙げてみたよ。

大石ゆかり

Scalaが非純粋関数型なのに対して、純粋な関数型言語というのも存在するんですね。

田島悠介

Haskellなどは純粋関数型言語の代表的な例になるね。関数型を使うことによってどのような利点があるのかを考えながらその特徴を捉えていこう。

大石ゆかり

分かりました。ありがとうございます!

オンラインのプログラミングスクールTechAcademyでは、Scalaオンライン講座を開催しています。

Scalaを使ってWebアプリケーションを開発することができます。

現役エンジニアがパーソナルメンターとして受講生に1人ずつつき、マンツーマンのメンタリングで学習をサポートし、最短4週間で習得することが可能です。

また、現役エンジニアから学べる無料のプログラミング体験会も実施しているので、ぜひ参加してみてください。

この記事を監修してくれた方

金澤秀知(かなざわひでとも)
フリーランスのITエンジニア

開発実績:大量の調査画像を分類するシステムの開発、業務用の人材管理アプリケーション開発、アクティブ・ラーニング用スマートフォンアプリ開発など

主にJava・Scalaを用いたサーバサイドプログラミングを中心としつつ、AWS・Azure・Firebaseなどのクラウドプラットフォームを使ったアーキテクチャ設計も行ってきた。開発にともなう課題として、自動テストを用いたソフトウェアの品質向上にも取り組んでいる。現在は高知県に住み、リモートワークを使った働き方を実践中。

初心者・未経験でもできる。まずはテックアカデミーに相談しよう

プログラミングを独学で学習していて、このように感じた経験はないでしょうか?

  • ・調べてもほしい情報が見つからない
  • ・独学のスキルが実際の業務で通用するのか不安
  • ・目標への学習プランがわからず、迷子になりそう

テックアカデミーでは、このような 学習に不安を抱えている方へ、マンツーマンで相談できる機会を無料で提供 しています。
30分間、オンラインでどんなことでも質問し放題です。

「受けてよかった」と感じていただけるよう カウンセラーやエンジニア・デザイナー があなたの相談に真摯に向き合います。

「自分に合っているか診断してほしい」
「漠然としているが話を聞いてみたい」

こんなささいな悩みでも大丈夫です。

無理な勧誘は一切ありません ので、まずはお気軽にご参加ください。
※体験用のカリキュラムも無料で配布いたします。(1週間限定)

今なら参加者限定の割引特典付き! 無料相談を予約する