IoT時代へようこそ
今はIoT(Internet of Things;モノのインターネット)の時代です。ソフトウェアシステムはいろいろなセンサやアクチュエータ,ITシステムと動的に繋がり,常に拡大しています。
このIoT時代ではプログラムは自律的に動作し,他のプログラムと分散しながら協調して動作する必要があります。つまり日々拡張するIoTシステム全体が協調して動作するように,個々のプログラムを開発する必要があります(図1)。
このような状況の中,プログラミングをワクワクドキドキしながら,学んでいく方法を紹介します。
図1 IoT時代におけるソフトウェアシステムは自律・分散・協調する必要がある
フレームワーク中心のプログラミングから脱却
ライブラリやフレームワークのプログラミング
従来のプログラミングでは,プログラミング言語を覚えてプログラミングするというよりも,その言語でよく使われるライブラリの癖やフレームワークの習慣を覚えて,そのフレームにピッタリ入るようにプログラミングしていました。例えば,Ruby on RailsやAndroid,JavaVM上の各種言語などがそうです。
メリット―生産性と信頼性の向上
多数のライブラリやフレームワークを覚え,それを使いこなすことにより,プログラムは簡単に作れるようになり,生産性は向上します。またライブラリやフレームワーク自身のコードはバグが少なく品質は安定しています。そしてフレームにぴったり入るようにガイドにしたがって作るため,全体の信頼性も向上します。まさにフレームワークを中心としたプログラミングは現在ではなくてはならない強力な武器です。
フレームワークによりプログラムが短時間に短い行数で作成できるので,プログラムを動かす喜びも早く味わえます。まさにプログラミング入門者にピッタリです。それにメジャーな言語,メジャーなフレームワークであればあるほど,多くの仲間と多くの書籍,多くの情報があります。このようにフレームワーク中心のプログラミングは入門者にとって,いいものです。
デメリット1―暗記と検索中心のプログラミング
しかしフレームワーク中心のプログラミングではAPIなどを覚える量が肥大化しています。リファレンスガイドが厚さを増し,1,000ページに達するのは時間の問題です。初心者にとっては覚えるとか,そのガイドで検索するというレベルではありません。
書籍にあるプログラムでは,使用するライブラリやフレームワークの探索はせずに最初から使用するライブラリの答えが書いてあります。しかし一番苦労するライブラリの検索は何も触れていません。だから書籍のプログラムを見て,そのまま動作させることは簡単にできても,実際の開発現場で役に立たない……となる訳です。実際にプログラミングするときには,正引きや逆引きの検索機能がないとフレームワークは使いこなせません。つまりフレームワーク中心のプログラミングは,暗記と検索中心のプログラミングなのです。
それに何より,暗記と検索中心のプログラミングは楽しくありません。最初は簡単に動作するので楽しいと思いますが,上級者になればなるほど,フレームワークに特化した知識ばかりが増え,そのフレームワークの仙人(専任)になってしまいます。そしてそれは他に転用できない知識となり,そのフレームワークの死とともに,亡くなってしまいます。
デメリット2―システムを超えられない,動的に対応できない
フレームワーク中心のプログラミングのデメリットとして,対象としているシステムの範囲を超えられないことも挙げられます。想定範囲内のことを一生懸命サポートしますが,動的な拡張については弱いものです。
IoT時代のソフトウェアシステムは冒頭でも言及したように,いろいろなものと動的に繋がる必要があります。個々のプログラムがそれぞれ自律的に分散動作していてもシステム全体では協調動作をする必要があります。これには静的で,対象が限定されているフレームワーク中心のプログラミングでは対応できません。
IoT時代に求められるプログラミングパラダイム
副作用のない関数型プログラミング
IoT時代のプログラミングに求められるパラダイムは,関数型プログラミングのパラダイムです。もちろん,オブジェクト指向も必要で,この両方のパラダイムが必要になってきます。
関数型プログラミングは,自律分散して動作するプログラムには欠かせない「副作用のないプログラム」の概念を持っています。副作用のないプログラムを目指すときは,この関数型プログラミングのパラダイムがピッタリです。これはオブジェクト指向では味わえない魅力です。フレームワーク中心のプログラミングでは副作用は考慮されていないことが多いでしょう。きっとフレームワーク中心のプログラミングでは,副作用をなくすためにコピーをしすぎてしまい,同期制御の嵐になるでしょう。
自然に動的拡張できる関数型プログラミング
また関数型プログラミングはその仕組みが単純です。ファーストクラスの関数や高階関数の概念がありますので,システムの対象を動的に拡張するときに大掛かりな仕掛けを必要とせず,自然に行えます。
オブジェクト指向では拡張のための仕掛けとして差分プログラミング(継承やコンポジションなど)がありますが,多くのオブジェクト指向プログラミングでは拡張はクラスに限定されます。またフレームワーク自身を拡張するのは,これはもうプログラマの仕事ではありません。
AI時代に求められる関数型プログラミング
IoTそのものとは関係ありませんが,今はAIの第3次ブームだと言われていて,深層学習(Deep Learning)が流行しています。関数型言語LispはAI用の言語として使われていました。これは関数型言語が持っていた,拡張性の高い柔軟性があったためです。このようにAIのプログラミングでも,この関数型プログラミングは重要になってきています。
楽しく学ぶ関数型プログラミング
プログラミングは楽しくなければならない
プログラミングを仕事にする人でも,趣味でプログラミングする人でも,楽しみながらプログラミングできたほうがいいに決まっています。関数型プログラミングにはその楽しさがあります。
これに対して,手続き型プログラミング(命令型プログラミング)はあまり楽しくないでしょう。その理由は,書籍のプログラムを見ても,命令ばかりしていて,一体全体,このプログラムが何をしたいのかは,プログラムを動かすまでわかりません。これでは楽しさは感じられません。
プログラムがわかりやすい
関数型プログラミングは状態を持ちません。このため,関数単体で閉じています。他の関数を見ることなく,その関数単体で意味がわかります。優れた名前付けをされた関数を見るだけで,全体のプログラムを読み解くことができます。
プログラムが作りやすい
関数型プログラミングでは状態を持たず,破壊的代入文を使わず,副作用を生じさせません。この制約の元にプログラミングします。手続き型やオブジェクト指向に慣れたプログラマにとっては,これは大変なことだと思うかもしれません。しかし制約があるからこそ,作りやすいということがあります。手続き型のように野坊主に自由に作るのは,初心者にとっては作りにくいものです。またオブジェクト指向のようにクラスという制約とは直交する関数型の制約で,オブジェクト指向と共存させて作るのもお勧めです。
Lispのススメ
関数型プログラミングをするときにはLispをお勧めします。この理由はLispがIoT時代のプログラミングを楽しく学ぶための言語として優れているからです(図2)。その理由を挙げていきます。
図1 IoT時代のプログラミングにはLispがお勧め
① Lispは完成していなくても部分実行ができる
Lispはインタプリタで実行できます。実行する部分だけが完成していれば動作します。このため,ちょこまかと実行してはプログラミングすることができます。小まめに動作させるので,動いた!という感動も早く味わえ,多く味わえ,長続きします。
② Lispには呪文は不要
LispにはJavaのpublic static void main(String[] argv)のような呪文は必要ありません。動作させたい関数をそのまま作るだけです。コンパイルも必要ありません。すぐに実行できます。このターンアラウンドタイムの短さも,プログラミングの楽しさに集中させます。
③ Lispは動的言語
Lispは動的に型付けされるため,型宣言は必要ありません。余分なことで頭を悩ませず,プログラミングに集中できます。またLispは動的言語で関数の再定義やクラスの再定義も動的に行えます。それもJavaのような面倒なリフレクションではなく,そのまま関数定義やクラス定義をするだけで行えます。動的な再定義さえも空気のように何も気にせずに,ただプログラミングに集中できます。
④ Lispは関数型言語の基本
LispはAIのアセンブラと呼ばれていますが,関数型プログラミングの仕掛けを原始的な機能としてすべて持っていますので,関数型プログラミングのアセンブラとも呼べます。関数型プログラミングのラムダ式やクロージャはもちろんLispから始まっています。遅延評価や無限リストなども,これらを使って基本から学ぶことができます。
IoT時代に必要な関数型プログラミングを楽しく学ぶのにまさにLispは最適な言語です。皆さんもぜひLispで楽しくプログラミングを始めてみてください。