目次
- はじめに
- 謝辞
- 執筆者と担当章
- 目次
第1章:Elixir小史
Elixir言語の特徴
- モダンな関数型言語
- アクターモデルによる並行処理と耐障害性
- 大規模システムでの利用
Erlang/OTP──Elixirの実行基盤
- Erlangとはどんな言語か
- Erlangが得意なこと・苦手なこと
- 関数型言語としてのErlang
- コンパイラ言語としてのErlang
- プロセスとアクターモデル
- Erlangにおけるプロセス
- アクターモデルによるプログラムデザイン
- OTPによるErlangの拡張
- OTP──Open Telecom Platform
- ビヘイビアによる設計の抽象化
Elixirの誕生
- Elixirが作られた背景
- 並行処理へのアプローチ
- BEAM言語としてのElixir
- Elixirの特徴的なシンタックス
- ElixirとErlang/OTPとの関係
- Elixirのプログラム実行
- OTPから見たElixirアプリケーション
- Elixirの発展
- Elixirのエコシステム
- Elixirのコミュニティ
Elixirの持つポテンシャル
- ネットワークアプリケーション
- ネットワークアプリケーションの構造
- Elixirによるネットワークアプリケーション実装のメリット
- Elixirで実装されたネットワークアプリケーション
- Webアプリケーション
- Webアプリケーションの構造
- Webアプリケーションフレームワーク
- PhoenixによるWebアプリケーション開発
- 機械学習
- 機械学習アプリケーションの構造
- Elixirによる機械学習
- Nxのエコシステム
- IoTデバイス
- IoTアプリケーションの構造
- IoTとElixirの親和性
- Nervesのエコシステム
まとめ
第2章:Elixirの基礎
Elixirのインストール
- macOS上でのElixirのインストール
- パッケージマネージャを利用したインストール
- Windows上でのElixirのインストール
- バージョン管理ツールasdfを用いたElixirのインストール
- asdfのインストール
- asdfを利用したElixirのインストール
- Dockerを利用したElixirの環境構築
- Elixirイメージを利用した環境構築
Elixirコードの実行方法
- IEx──REPL環境を提供するCLIアプリケーション
- Livebook──ElixirコードをGUIで実行できるアプリケーション
- ファイルからの実行
- コンパイルして実行する場合
- スクリプトとして実行する場合
基本的な文法
- 変数
- 代入ではなく束縛
- 不変性
- 演算子
- 算術演算子──数値計算を行う基本的な演算子
- 比較演算子──値の比較を行う基本的な演算子
- 論理演算子──論理計算を行う基本的な演算子
- パイプ演算子
- マクロ
制御フロー
- if,unless──単独の条件式による条件分岐
- cond──条件式による条件分岐
- case──パターンマッチによる条件分岐
まとめ
第3章:基本的な型とパターンマッチ
基本的な型
- 整数──整数を表す型
- 浮動小数点──小数点を表す型
- 真偽値──真と偽を表す型
- アトム──名前付きの定数を表す型
- 文字列──文字列を表す型
- 文字リスト──文字コードのリストを表す型
- リスト── 連結リストで複数の値をまとめる型
- タプル──連続メモリ空間で複数の値をまとめる型
- マップ──複数のキーと値のペアを表す型
- キーワードリスト──連結リストで複数のキーと値のペアを表す型
- 構造体──任意のデータ構造を表す型
- 範囲──範囲を表す型
- 日付と時間──日付と時間を表す型
シジル──リテラルを表現する記法
- ~Cと~c──文字リストを表すシジル
- ~Sと~s──文字列を表すシジル
- ~Wと~w ──単語のリストを表すシジル
- ~Rと~r ──正規表現を表すシジル
- 日付や時刻を表すシジル
パターンマッチ──データとパターンの照合
- パターンマッチとは何か
- さまざまなパターンマッチ
- 変数のパターンマッチ
- タプルのパターンマッチ
- リストのパターンマッチ
- マップのパターンマッチ
- 文字列のパターンマッチ
- パターンマッチが可能な場所
- 関数の引数
- case式
- ピン演算子──パターンマッチにおける変数の固定
- ガード節──パターンマッチへの条件の追加
まとめ
第4章:モジュール
モジュールと関数によるプログラムの構造化
- モジュールの作成
- 無名関数
- 別のモジュールで定義した関数の呼び出し
- 関数のアリティ表記
- 関数キャプチャ
- 関数キャプチャを引数に利用
- キャプチャ演算子&を用いて無名関数を作成
- 標準モジュール
String──文字列操作を扱う標準モジュール
- length──長さを取得する関数
- contains?──指定の文字列を含んでいるかどうかを返す関数
- upcase──文字列を大文字にする関数
- downcase──文字列を小文字にする関数
- capitalize──文字列の先頭を大文字にする関数
- replace──文字列を置換する関数
- reverse──文字列を逆順にする関数
- split──文字列を分割する関数
- split/1
- split/3
- slice──部分文字列を返す関数
- slice/2
- slice/3
File──ファイル操作を行う標準モジュール
- read──ファイルを読み込む関数
- write──ファイルに書き出す関数
IO──標準入出力を扱う標準モジュール
- puts──文字列を出力する関数
- inspect──値を文字列に変換して出力する関数
- read──文字列を読み込む関数
Enum──コレクションを「いい感じ」に扱う標準モジュール
- map──各要素を変換する関数
- filter,reject──フィルタリングする関数
- filter
- reject
- all?,any?──要素を検証する関数
- all?
- any?
- max,min──最大値,最小値を取得する関数
- max
- min
- reduce──畳み込みを行う関数
- パイプ演算子との併用
Map──マップを「いい感じ」に扱う標準モジュール
- new──マップを生成する関数
- new/0──空のマップを生成する関数
- new/1──コレクションからマップを生成する関数
- new/2──コレクションと関数からマップを生成する関数
- has_key?──マップにキーが含まれているかどうかを返す関数
- get──マップからキーを指定して値を取得する関数
- put──マップにキーと値を挿入する関数
- update──マップを更新する関数
- merge──マップをマージする関数
- Map.merge/2
- Map.merge/3
- drop──マップから指定したキーを削除する関数
- keys──マップからすべてのキーを取り出す関数
- values──マップからすべての値を取り出す関数
- to_list──マップをリストに変換する関数
Stream──コレクションを遅延評価する標準モジュール
- map──各要素を変換する関数
- filter,reject──フィルタリングする関数
- filter
- reject
- iterate──無限のストリームを生成する関数
- EnumとStreamのどちらを使うか
ExUnit──Elixirの単体テスト標準モジュール
- テストをすべて実行
- 一部のテストのみを実行
- モジュールのテスト
- doctest──コメントにテストを記述する
まとめ
第5章:Mixを使ったElixirプロジェクトの開発
Mixの基本的な使い方
- 新しいプロジェクトの作成
- mix.exs──プロジェクトの設定を管理するファイル
- 依存関係の管理
- Hex──パッケージマネージャ
- プロジェクト内でIExの起動
- プロジェクト設定の管理
Mixタスク──Elixir開発を支える便利なコマンド
- mix new ──プロジェクトの作成
- mix deps.get ──依存パッケージの取得
- mix compile──プロジェクトのコンパイル
- mix test──テストの実行
- mix release──アプリケーションのリリース
- mix format──コードフォーマット
- mix escript──Erlang/Elixirのスクリプト
- mix escript.build──escriptプログラムを作成
- mix escript.install──escriptプログラムをローカルにインストール
- mix help──Mixタスクの一覧表示とヘルプの表示
- Mixタスクの作成
開発に便利なTips
- observer──GUIのモニタリングツール
- dbg/2──デバッグ用のマクロ
まとめ
第6章:並行プログラミング
プロセスによる並行プログラミングの実現
- プロセスの生成とメッセージの送受信
- プロセスにメッセージを送信する
- プロセスがメッセージを受信する
- プロセスが別のプロセスを生成する
- プロセスの監視
- プロセスが別のプロセスをリンクする
- プロセスが別のプロセスをモニタする
- 高度なプロセス
- タスク──バックグラウンドで関数を実行するプロセス
- エージェント──状態を持ったプロセス
OTPによる並行プログラミングの実現
- GenServerビヘイビア──サーバの振る舞いを抽象化したパターン
- カウンタサーバを実装してみよう
- カウンタサーバの初期化
- カウンタサーバの起動
- 同期呼び出しと非同期呼び出し
- カウンタサーバの同期呼び出し
- 同期呼び出しのカウントアップ
- 同期呼び出しのカウントダウン
- カウンタサーバの非同期呼び出し
- Supervisorビヘイビア──プロセスの監視と再起動
- Supervisorモジュールによる実装
- 再起動設定
- Counterをスーパーバイザーで監視する
まとめ
第7章:Phoenixの概要
Phoenixとは何か──Elixir製のWebアプリケーションフレームワーク
- Phoenixが解決すること──リッチなWebアプリケーション開発の効率化
- Phoenixの特徴──高い生産性とパフォーマンスを兼ね備えたフレームワーク
Phoenixの基礎知識
- Phoenixのディレクトリ構成
- mix.exs──プロジェクト全体の設定ファイル
- assetsディレクトリ──フロントエンドのリソースを格納するディレクトリ
- configディレクトリ──アプリケーションの設定情報を格納するディレクトリ
- depsディレクトリ──Mixのすべての依存関係があるディレクトリ
- libディレクトリ──アプリケーションのソースコードを格納するディレクトリ
- privディレクトリ──ソースコードには直接含まれないリソースを管理するディレクトリ
- testディレクトリ──テストコードを格納するディレクトリ
- ルーティング──URLとコントローラの対応
- リクエストライフサイクル──Phoenixにおけるリクエスト処理の流れ
- ルーティングファイルrouter.exの書き方
- ルーティングの特殊な関数──resourcesとlive
- 検証済みルート
- コントローラ
- アクションの定義
- レンダリングの指定
- リダイレクトの指定
- フラッシュメッセージの表示
- ビューとテンプレート
- HTMLのレンダリング
- JSONのレンダリング
- モデル
- Ecto──データベースを操作するライブラリ
- コンテキスト──機能のグルーピング
- Mixタスクによるスキャフォールディング
- mix phx.gen.html──HTMLリソースの生成
- mix phx.gen.json──JSONリソースの生成
- mix phx.gen.live──LiveViewリソースの生成
- mix phx.gen.auth──ユーザー認証機能の生成
- そのほかのスキャフォールディング
Phoenixの基本的な使い方
- PostgreSQLの起動
- Phoenixプロジェクトジェネレータのインストール
- Phoenixプロジェクトの作成
- データベースの初期設定
- Phoenixの起動
まとめ
第8章:Ectoによるデータベース操作
Ectoとは何か──Elixir製のデータベースライブラリ
- Ectoが解決すること──データベースへのさまざまな操作をサポート
- Ectoの特徴──データマッパおよびクエリビルダ
Ectoの基礎知識
- 主要コンポーネント
- Ecto.Repo──データベースのラッパ
- Ecto.Query──Elixirの文法で書けるクエリビルダ
- Ecto.Schema──テーブル構造とElixir構造体のマッピング
- Ecto.Changeset──データ変更の管理
- 便利な機能
- データベースの作成,削除
- マイグレーション──データベースのスキーマに対する変更
- トランザクション──ひと塊の分けることができない操作
- シードデータの投入
- データリセット
Ectoの基本的な使い方
- スキーマモジュールとマイグレーションファイルの作成
- 銀行口座スキーマモジュールとマイグレーションファイルの作成
- 取引スキーマモジュールとマイグレーションファイルの作成
- マイグレーションの実行
- スキーマモデルどうしの関連付け
- TransferとAccountの関連付け
- AccountとTransferの関連付け
- バリデーション──入力データの検証
- Transferのバリデーション
- Accountのバリデーション
- データの操作
- 作成(Create)
- 読み出し(Read)
- 更新(Update)
- トランザクション
- 取引の読み出し
- 削除(Delete)
- シードデータの投入
まとめ
第9章:phx.gen.authによる認証
phx.gen.authとは何か──ビルトインのMixタスク
- phx.gen.authが解決すること──リッチな認証機能の実装
- phx.gen.authの特徴──関連ファイルが生成されることによる処理の追跡とカスタマイズの容易さ
phx.gen.authの基礎知識
- 認証方式
- 認証の基本機能
- 新規登録
- ログイン/ログアウト
- 認証の補助機能
- 確認メールによる本登録
- メールアドレスとパスワードの変更
- パスワードリセット
- アクセスコントロール
- pipelineによる処理の共通化
- 認証のスコープ
phx.gen.authの基本的な使い方
- 認証機能の追加
- パスワードバリデーションの変更
- テストの修正
- メールの送信方法の変更
- Amazon SES
- SendGrid
- メール本文の設定
まとめ
第10章:LiveViewによるフロントエンドの開発
LiveViewとは何か──Elixirで実装するリアルタイムWeb
- LiveViewが解決すること──効率的なSPAの開発
- LiveViewの特徴──WebSocketによる複数クライアント間でのデータのやりとり
LiveViewの基礎知識
- LiveViewのディレクトリ構成
- LiveViewのライフサイクル
- 状態の管理と更新
- UIの制御
- HEExテンプレート──EExを拡張した新しいテンプレートエンジン
- DOMバインディング──ElixirによるDOMイベントのハンドリング
- ルーティング──URLとLiveViewの対応
LiveViewの実践的な使い方
- コンポーネント分割
- Phoenix.Component──ステートレスなコンポーネント
- Phoenix.LiveComponent──ステートフルなコンポーネント
- ファイルアップロード
- PubSubによるリアルタイム更新
- JavaScriptとの連携
- JS Hooks──LiveViewとJavaScriptの間でのDOMイベントの送受信
- JS Module──LiveViewからJavaScriptのユーティリティ操作の実行
- Phoenix.LiveViewTestによる結合テスト
まとめ
第11章:実践的なWebアプリケーションの開発
ブログアプリケーションRealWorldの実装
- RealWorldとは何か
- 開発する機能
記事のCRUD機能の開発
- スキャフォールディングの実行
- マイグレーションファイルの変更
- ルーティングの設定
- マイグレーションの実行と動作確認
コメント機能の開発
- コメントのスキーマモジュールとマイグレーションファイルの作成
- Commentスキーマモジュールの変更
- マイグレーションファイルの変更
- 記事とコメントの関連付け
- マイグレーションの実行と動作確認
タグ機能の開発
- タグの仕様
- 記事とタグを関連付けた保存
- タグのスキーマモジュールとマイグレーションファイルの作成
- 記事とタグを関連付けるスキーマモジュールとマイグレーションファイルの作成
- Articleスキーマモジュールの変更
- 記事とタグを関連付けて保存する関数の追加
- マイグレーションの実行と動作確認
- タグによる記事検索
認証機能の開発
- phx.gen.authによる認証機能の追加
- 記事とユーザーの関連付け
- マイグレーションファイルの作成
- Articleスキーマモジュールの変更
- コメントとユーザーの関連付け
- マイグレーションファイルの作成
- Commentスキーマモジュールの変更
- アクセスコントロール
LiveViewによるRealWorldの開発
- 画面の実装──記事一覧/作成/編集/削除/詳細
- 記事の一覧
- 記事の作成
- 記事の編集
- 記事の削除
- 記事の詳細
- タグによる記事検索
- 記事に紐付くタグの保存
- 記事に紐付くタグの表示
- 記事の一覧でのタグによる記事検索
- タグによる記事検索のテスト
デプロイ
- phx.gen.releaseによるリリース作成用ファイルの作成
- Fly.io CLIのインストール
- macOSでのインストール
- Windowsでのインストール
- Linuxでのインストール
- Fly.ioへのアプリケーションのデプロイ
まとめ
第12章:行列演算ライブラリNxの概要
Nxとは何か
- Nxが解決すること
- Nxのバックエンド
- BinaryBackend──純Elixir製のバックエンド
- EXLA.Backend──XLAを使用したバックエンド
- Torch.Backend──libTorchを使用したバックエンド
- Evision.Backend──OpenCVを使用したバックエンド
Nxの基本的な使い方
- 行列の生成
- Nx.tensor/2──さまざまな値からの生成
- Nx.iota/2──指定した行列の形状で生成
- Nx.broadcast/3──行列を上書き
- Nx.Randomモジュール
- 行列の情報の取得
- Nx.shape/1──行列の形状を取得
- Nx.size/1──行列の要素数を取得
- Nx.rank/1──行列のネストの深さを取得
- Nx.axes/1──行列の軸を取得
- 行列の演算
- 四則演算
- Nx.dot/2──内積の演算
- 比較演算
- 行列の変形
- Nx.reshape/2──行列の変形
- Nx.transpose/2──転置行列に変換
- Nx.flatten/2──行列の平坦化
- Nx.slice/4──行列の切り取り
- Nx.slice_along_axis/4──軸指定可能な行列の切り取り
- 行列から値の取得
- 数値で指定した位置の値を取得
- 範囲で指定した位置の値を取得
- Nx.argmax/2──最大値の位置を返す
- Nx.reduce_max/2──最大値を返す
- 行列データの変換
- Nx.to_number/1──数値型に変換する
- Nx.to_list/1──行列をリストに変換する
- Nx.to_flat_list/2──行列を平坦なリストに変換する
- Nx.to_batched/3──行列をいくつかのまとまりのリストに変換する
まとめ
第13章:Axonの概要と機械学習システム開発の進め方
Axonとは何か
- Axonが解決すること
- Axonの特徴
Axonの基本的な使い方
- MNIST──手書き数字の画像データセット
- 推論モデルの構築手順
SciDataとNxによる学習データの準備
- SciDataによるデータのダウンロード
- Nxによるデータの整形
Axonによるモデルの構築
Axon.Loopによるモデルの学習と可視化
- Axon.Loop.trainer/4──損失関数と最適化アルゴリズムの設定
- Axon.Loop.metric/4──算出する評価指標の設定
- Axon.Loop.kino_vega_lite_plot/4──学習過程を描画
- Axon.Loop.run/4──学習の実行
Axon.Loopによるモデルの検証
Axon.predict/4──推論の実行
- Axon.predict/4の実行結果
- Nx.argmax/2──結果の絞り込み
- Nx.to_heatmap/2を使用した検証
まとめ
第14章:機械学習向けのライブラリ
Kino──Livebook用のUIライブラリ
- Kinoとは何か
- Kinoの特徴
- スマートセル
- Database connection
- SQL query
- Chart
- Data transform
- Map
- Neural Network task
- Slack Message
- Deploy
StbImage──軽量画像読み書きライブラリ
- StbImageとは何か
- StbImageの特徴
- StbImageの使い方
- StbImage.read_file/2──画像の読み込み
- StbImage.read_binary/2──バイナリデータの読み込み
- StbImage.resize/3──画像のリサイズ
- StbImage.write_file/3──画像の書き出し
- StbImage.to_nx/2──画像データのNx.Tensorへの変換
Evision──OpenCVラッパー
- Evisionとは何か
- Evisionの特徴
- Evisionの使い方
- Evision.imread/1──画像の読み込み
- Evision.imwrite/1──画像の書き出し
- Evision.resize/2──画像のリサイズ
- Evision.rotate/2──画像の回転
- Evision.rectangle/4──画像に長方形を描画
- Evision.putText/6──画像に文字を描画
- Evision.Mat.roi/2──画像の切り取り
- Evision.Mat.to_nx/2──画像データのNx形式への変換
- Evision.Mat.from_nx_2d/1──Nx.TensorをEvision.Matに変換
- Evision.DNN.DetectionModel──物体検知を行うモジュール
Bumblebee──学習済みTransformerモデル提供ライブラリ
- Bumblebeeとは何か
- Bumblebeeの特徴
- Bumblebeeの使い方
- 利用可能なモデル
まとめ
第15章:実践的なAxonアプリケーションの開発
画像分類を行うWebアプリケーションの実装
- 画像分類とは何か
- 実装する機能の説明
- 追加ライブラリのインストール
LiveViewページの作成
ファイルアップロード機能の実装
- アップロードの設定
- フォームの作成
- サムネイル画像の表示
学習済みモデルでの画像分類機能の実装
- 画像データの変換
- バイナリデータからサムネイル画像の表示
- Bumblebeeで学習済みモデルの読み込み
- Nx.Servingによる推論サーバの起動
- 推論結果の表示
まとめ
第16章:Nervesの概要
Nervesとは何か
- Nervesが解決すること
- リソース制約の厳しいデバイスへの対応
- 実世界とのインタラクティブなデータ処理
- 詳細なドメイン知識なしでのIoTデバイスの開発
- さまざまなインターネット通信方式への対応
- Nervesの特徴
- IoTシステムに適した実行環境
- 潤沢なフレームワーク
- 円滑に開発を進められるツール
Nervesの動作するIoTボード
- 動作要件
- Buildrootのサポート
- プロセッサの種類や性能
- ストレージデバイス
- 公式サポートされているターゲット
- Raspberry Piファミリ
- BeagleBoneファミリ
- そのほかのデバイス
まとめ
第17章:Nervesでの開発の進め方
用意するもの
- ホスト開発環境の準備
- 推奨されるOS環境
- Nervesのためのライブラリのインストール
- Nerves.Bootstrapのインストール──Nerves専用のジェネレータ
- fwupのインストール──Nervesファームウェアの作成ツール
- SSH接続のための鍵ペアの作成
- ターゲットとなるハードウェア
Nervesプロジェクトの基本的な開発の進め方
- プロジェクトの作成とビルド
- mix nerves.new──プロジェクトの作成
- 環境変数MIX_TARGETの設定──ターゲットの設定
- インターネット接続の設定
- mix deps.get──依存ライブラリの取得
- mix firmware──ファームウェアのビルド
- Nervesの動作確認
- mix burn──microSDカードへのファームウェアの書き込み
- ssh nerves.local──Nervesデバイスへのアクセス
- Hello Nerves!
- IExの終了
- Nervesファームウェアのネットワーク越しの更新
- ソースコードの書き換え
- mix upload──SSH経由での更新
- 更新結果の確認
まとめ
第18章:Elixir Circuitsによるモジュールの制御
Elixir Circuitsとは何か──Elixir/Nerves向けのモジュール制御ライブラリ
- Elixir Circuitsが解決すること
- Elixir Circuitsの特徴
モジュールの通信方式
- GPIO──1ビット単位の制御に向いた通信方式
- I2C──バス上のアドレスを指定した通信方式
用意するもの
- Grove Base Hat
- Groveモジュール
- Groveモジュールの組み立て
Elixir Circuitsの使い方
- ライブラリの追加
- Circuits.GPIOによるLED点滅の制御
- Circuits.GPIO.open──GPIOピンを設定する関数
- Circuits.GPIO.write──GPIOピンに値を書き出す関数
- Circuits.GPIO.close──GPIOピンのリファレンスを解放する関数
- LEDを制御するドライバ関数のライブラリ化
- Circuits.GPIOによるボタン入力の検知
- Circuits.GPIO.read──GPIOピンの値を読み込む関数
- Circuits.GPIO.set_interrupts──GPIOピンの入力値の変化を検知する関数
- ボタンを制御するドライバ関数のライブラリ化
- Circuits.I2Cによる温度と湿度の測定
- Circuits.I2C.detect_devices──モジュールのI2Cアドレスを確認する関数
- Circuits.I2C.open──I2Cバスを開く関数
- Circuits.I2C.write──I2Cモジュールに値を書き出す関数
- Circuits.I2C.read──I2Cモジュールの値を読み込む関数
- Circuits.I2C.close──I2Cバスのリファレンスを解放する関数
- 温湿度センサを制御するドライバ関数のライブラリ化
まとめ
第19章:実践的なIoTアプリケーションの開発
開発するもの
データ受け取りサーバの作成
- Phoenixプロジェクトの作成
- IPアドレスの設定
- mix phx.gen.jsonによるREST APIの作成
- 動作の確認
データのリアルタイム表示部の作成
- 表示するデータの取得
- 表示ページの作成
- ルーティングの設定
- 動作の確認
データ送信モジュールの作成
- ライブラリの追加
- Phoenixサーバへのデータの送信機能の作成
- Nervesファームウェアのビルドと更新
- 動作の確認
ボタンの押下によるデータ測定
- ボタンの押下に応じたプロセスの実行
- Nervesファームウェアのビルドと更新
- 動作の確認
- 自動実行の設定
まとめ
- あとがき
- 索引
- 著者プロフィール