By Chris Eidhof, Florian Kugler, and Wouter Swierstra
和田祐一郎 訳
* 本書はオンライン版(PDF/epub/mobi)のみの販売です。
Swiftは、プログラミングにおける新たな世界への扉を開きます。本書ではその新たな世界を探検します。Swiftの生みの親Chris Lattnerは次のように述べています。「『CのないObjective-C』は何か退化したように感じてしまうかもしれませんが、ジェネリクスと関数型プログラミングのコンセプトを導入したことでSwiftはデザイン領域を劇的に拡張しました。」
本書では、より明瞭かつ表現力の高いコードを書くために、関数型プログラミングのコンセプトを説明し、その実践的な活用をSwiftで簡単に行う方法を説明します。
Apple公式のSwiftドキュメントが手に入り、他にも多数の関連書籍がすでに出版されているにもかかわらず、なぜ本書を書こうと思ったのでしょうか?また新たに出現したプログラミング言語について、なぜまた新たな書籍が必要とされるのでしょうか?
本書は、読者のみなさんに「関数的に」考えることを学んでもうらうための本です。Swiftは、関数型プログラムを書く方法を読者のみなさまに説明するための適切な言語機能を持っていると考えています。しかし、何がプログラムを「関数型」にするのでしょうか?そもそもなぜ関数型プログラミングを学ばなければならないのでしょうか?
関数型プログラミングに正確な定義を与えることは困難です。それはオブジェクト指向プログラミングや他のパラダイムに正確な定義を与えることが困難であることと同じです。本書では、その定義の代わりとして、Swiftを使ってうまくデザインされていると我々が考える関数型プログラムが持つ、いくつかの特性に注目します。
モジュラー性:関数型プログラマーは、プログラムを代入とメソッド呼び出しの連続と捉えるのではなく、各プログラムはより小さなコンポーネントに繰り返し分解できること、そしてこれらすべてのコンポーネントを関数適用で組み合わせることでプログラム全体を構成することを重点的に考えます。もちろん、この大きなプログラムを小さなコンポーネントに分解するということは、各コンポーネント間での状態の共有を避けることによってのみ成立します。これは次のポイントにつながります。
変更可能な状態の慎重な取り扱い:関数型プログラミングは「値指向プログラミング」であると(半ば揶揄として)言われることがあります。オブジェクト指向プログラミングでは、カプセル化された状態を持つクラスとオブジェクトのデザインに注力します。しかし関数型プログラミングでは、値によるプログラミングの重要性を強調し、変更可能な状態やその他の副作用には関わりません。関数型プログラムは、変更可能な状態を避けることでより簡単に命令型やオブジェクト指向で書かれたプログラムと組み合わせられます。
型:そして最後に、うまくデザインされた関数型プログラムは「型」を有効利用します。コードの構造化には、データや関数の型を注意深く選択することが最も役立ちます。Swiftは、強力な型システムを持っています。これを効率的に利用すれば、コードをより安全でより強固にできます。
これらは、Swiftプログラマーが関数型プログラミングコミュニティから学べる重要な知識であると考えています。本書を通して多くの例やケーススタディでこれらのポイントを説明します。
我々の経験上、関数的な考え方を学ぶことは簡単ではありません。これまでに学んできた問題の分解方法とは違います。forループに慣れきったプログラマーにとっては、再帰で混乱するかもしれません。代入文やグローバルな状態変数が存在しないことも足かせになります。そして、クロージャやジェネリック型、高階関数やモナドは何か異質なものに見えます。
本書の読者には、Objective-C(または他のオブジェクト指向言語)でのプログラミング経験があることを想定しています。Swiftの基礎やXcodeでのプロジェクトのセットアップなどの説明は本書で行いませんが、必要に応じてAppleの公式ドキュメントの参照リンクを提供します。もしあなたがプログラミングを始めたばかりであれば、本書はまだ読むべき本ではないかもしれません。Swiftプログラムを問題なく読むことができ、クラスやメソッド、変数など、プログラミングにおける一般的な考え方に慣れていなければ厳しいでしょう。
本書では、関数型プログラミングにまつわる謎を解き、人々が関数型プログラミングに対して感じるであろう偏見を取り除きたいと思っています。よりよいコードを書くために、数学の博士号は必要ありません!また、関数型プログラミングがSwiftでプログラムを書くための唯一の方法であるというわけでもありません。関数型プログラミングを学ぶことは重要なツールを新たに手に入れることであり、どの言語を使う場合であってもより優れた開発者になれると考えています。
Swiftにおける関数は「第一級の値(first-class value)」です。これはつまり、関数を他の関数の引数として渡すことができ、関数は新たな関数を返せる、ということです。数値・真偽値・構造体などの単純型に慣れている方にとっては、奇妙に感じる考え方かもしれません。本章では、なぜ第一級関数が便利なのかを説明し、初めての関数型プログラムを実際に動かしてみます。
前章では高階関数のコンセプトを紹介し、関数がどのように他の関数の引数として渡されるかをお見せしました。しかし、その例は現実に書くようなコードからは遠いものです。この章では、より現実に近い例を取り上げ、高階関数を使って既存のオブジェクト指向APIを小さい関数型コードでラッピングする方法をご紹介します。
関数を引数に取る関数は「高階関数」と呼ばれます。本章では、Swiftの標準ライブラリの配列に実装されているいくつかの高階関数を紹介します。また、Swiftのジェネリック型を紹介し、配列を使った複雑な処理の構築方法をお見せします。
Swiftのオプショナル型は、存在しないかもしれない、または計算が失敗する可能性がある値の表現に使用します。本章では、オプショナル型を効果的に利用する方法と、この型が関数型プログラミングパラダイムにどうフィットするかを説明します。
近年、Objective-Cの世界においてテストがより一般的になってきています。多くの主要ライブラリが継続インテグレーションツールで自動テストされています。単体テストの標準フレームワークはXCTestです。また、サードパーティから多くのフレームワーク(Specta、Kiwi、FBSnapshotTestCaseなど)がリリースされていて、Swiftでも新たに多くのフレームワークが開発されています。
これらのフレームワークはすべて似たパターンに沿っています。テストは通常、コードフラグメントとその期待される結果値で構成されています。ライブラリによって異なるレベルでテストを行います。例えば、個別のメソッドをテストするもの、クラスをテストするもの、インテグレーションテストを行うもの(アプリ全体を走らせる)があります。本章では、機能特性を基にSwiftの関数をテストする小さなライブラリを、改善を繰り返しつつ段階的に構築します。
Swiftには、値の変更を制御する仕組みがいくつか用意されています。本章では、それらの仕組みがそれぞれどのように動作するのかということや、値型と参照型の違い、そして変化可能な状態の利用を制限することの意義についてお話します。
本書では、Swiftアプリケーションのデザインと実装において型が担う役割の重要さを伝えたいと思っています。本章では、アプリケーションが使うデータを正確に表現するための型である、列挙型(enumeration)を説明します。
前章では、個々のアプリケーションに適したデータ型を定義するために列挙型を利用する方法をみてきました。本章では、再帰的な列挙型を定義し、これが二分探索木やトライ木など、効率的かつ永続性を持ったデータ構造の定義に利用できることをお見せします。
本章では、関数型のダイアグラム記述法と、それをCore Graphicsで描画する方法を紹介します。Core Graphicsを関数型レイヤーにラッピングすることで、よりシンプルかつ合成可能なAPIが手に入ります。
本章ではジェネレータ(generator)とシーケンス(sequence)を紹介します。これらはSwiftのforループを駆動させる裏の仕組みであり、続く章でお見せするパースライブラリの基礎となるものです。
パーサは便利なツールです。トークンのリスト(通常は文字のリスト)を取り、それを構造に変換します。通常、パーサはBisonやYACCなどの外部ツールを使って生成されます。本章では外部ツールの代わりに、自分でパーサを書くときに役立つライブラリを構築します。関数型言語はこのようなタスクにとても適しています。
パーサライブラリを書くアプローチはいくつか存在しますが、ここではパーサコンビネータライブラリを構築します。パーサコンビネータとは、いくつかのパーサを入力値として、新たなパーサを出力する高階関数です。このライブラリは、Haskellライブラリ(2009)を移植し、少々変更を加えたものです。
まずは基礎となるコンビネータをいくつか定義するところから始めます。その上で、コンビニエンス関数をいくつか定義し、最後に1+3*3のような数式をパースし計算する例をお見せします。
本章では、シンプルなスプレッドシートアプリのパーサ、評価器、そしてGUIを作ります。スプレッドシートは行と列として整理されたセルで構成されます。各セルには10*2などの式が入ります。式をパースした結果として、その構造を表現する木構造「抽象シンタックスツリー」を構築します。そしてこのシンタックスツリーを評価して各セルの計算を行い、TableViewに表示します。
本章では、関手(functor)、アプリカティブ関手(applicative functor)、モナド(monad)といった、関数型プログラミングに登場する用語や一般的なパターンを説明します。これらの一般的なパターンを理解しておくことで、データ型の設計やAPIで提供すべき関数の選択に役立ちます。
objc.ioの共同設立者。ここ最近の開発者人生をAppleのプラットフォーム上での開発に捧げるプログラマ。それ以前はHaskellプログラマという経歴を持つ。
objc.ioの共同設立者。長い間オブジェクト指向プログラミングを専門にしていた開発者だが、モナドや自己関手は常に支配下に置いてある。
15年以上の関数型プログラミングの経験を持つ。産業界で働き、教育機関で教え、研究論文を出版するが、それらすべてが関数型プログラミングに関連している。
株式会社プログラミングシステム社代表取締役。「トラクション」「ハイパフォーマンスブラウザネットワーキング」「JavaScriptで学ぶ関数型プログラミング」等を翻訳。
もちろん、最新のSwift言語機能を活用しています!
GitHubに置いてあります。
本書はオブジェクト指向プログラミングについての実践的な知識と、Appleが提供するSwift言語ガイドを理解していることを前提としています。
現在はeBookのみの販売を予定しています。今後、多数のご要望をいただけば書籍化も検討いたします。
かかっていません。すべてのフォーマットがDRMフリーです。
同タイトルのアップデートは無料です。本書の原書もSwift 1.xから2.xへアップデートした際のアップデートは無料で提供されました。今後のアップデートについても同様の予定です。