関数型プログラミングに始めて触れる方にスキルを身につける/教えるためのトレーニング方法について紹介します。
私の所属先では、サーバサイドの言語として以前はPHPをメインとして開発していましたが、数年前から新規のシステムや既存システムのリプレイス時の言語としてKotlinを採用しています。
Kotlinは純粋関数型言語ではないですが関数型の特徴を持った言語であり、その恩恵を受けた開発が魅力のマルチパラダイムなプログラミング言語です。他方、PHPは比較的命令型・オブジェクト指向型の言語といえます。ゆえに、PHPを書いていた人がいきなり "Kotlinらしい" 関数型の言語機能を利用したコードを書けるようになるためには少々のハードルがあります。
そこで、Kotlinを用いた開発のオンボーディングとして初学者向けの問題集をトレーニング資料として用意し、自学自習を促すことでハードルを超えやすくする取り組みを始めています。
このセッションでは、その自学自習用の資料で具体的にどのような意図でどのような内容に触れているかを解説しつつ、効率的な学び方やペアプロを用いた教え方やついて触れられればと考えております。また、関数型言語の初学者にとって、どのようなことが関数型言語を学ぶ入口であるかのイメージが湧くようなセッションを目指します。
以下の内容をお話する予定です。
よろしくお願いいたします。
Haskell では、GHC 9.10 から WASM Backend で JavaScript FFI が使えるようになりました。これにより、WASM にコンパイルされた Haskell プログラムをブラウザで動かして DOM を弄ったり、あるいはサーバサイドのランタイムで JavaScript の API を呼び出せるようになりました。
本講演では、実際に Cloudflare Workers 上で動作するブログシステムを、バックエンドからフロントエンドまで全て Haskell を使って開発した経験を通し、GHC の WASM クロスコンパイラを使った開発の現在について概観します。
当該ブログシステムのフロントエンドは Miso、サーバレスバックエンドは自前の Cloudflare Workers バインディングライブラリによって記述されていますが、ここで Servant を用いることで如何に両者の間でシームレスにデータをやり取りできるかについて紹介します。
また、この開発の過程でJavaScript のオブジェクトシステムとある程度両立する高水準 FFI ラッパーライブラリを開発しました。こちらでは GADTs や Linear Types などを使ってある程度の型安全性と効率を実現しており、こうした FFI 用ライブラリのデザイン手法についてもご紹介します。
Haskell、WASM、Servant、API、Cloudflare Workers、サーバレス、GADTs、Linear Haskell
講演者は Haskeller ですが、最近は業務では Rust を書いています。その過程でどうしても do 式が使いたくなり、Rust で do 式を使うための qualified_do
を開発しました。
まずは、この qualified_do
によるプログラムの例を紹介し、かなり便利なものであるというお話をします。
特に、do式によって Rust の ?
構文糖衣に対する代替的な記法が実現できることや、イテレータの合成や proptest によるランダムデータ生成を見通しよく書けることなどを見ます。
do式を使うには、Monad や Applicative といった構造に類似の演算を備えている必要があります。「Haskellのひとたちが使っている難しそうな……」と身構えるかもしれませんが、do式のうちどういう構文がつかえるかという基準を念頭におくと、こうした階層を自然に理解できることを紹介します。また、Rust でモナド等を抽象化するために Generic Associated Types を使うトリックについても欠点と利点を解説します。
Rust や Linear Haskell のようなリソース管理にうるさい言語では、資源管理にどこまで敏感かによって、Monadの階層は複数に分裂します。本講演では、最後に発展的話題としてこうしたフレーバーの異なる複数の Monad 階層の関係について触れ、また Rust と Linear Haskell の型システムの違いにより、Rust では資源に敏感な do 式をより広い型に適用できるという事を説明します。
Rust、線型型、所有権、do式、プログラミング言語意味論、モナド、Functor、Applicative、Haskell、Linear Haskell
定理証明支援系であり純粋関数型プログラミング言語でもある、Lean について紹介します。
Lean はまだ新しい言語であり知名度も低いので、このトークではLean言語の名前と特徴を憶えてもらうことを目標とします。
LISPは記号処理に特化して初期の人工知能研究を牽引した言語であり、実用的な関数プログラミングを提供した最初の言語といえるでしょう。
現在のLisp族の末裔たちも関数プログラミングのための機能を備えている一方、後続の関数型言語(ML族)が持つ静的型や参照透過性、モナドなどの機能は持っていません。
このトークでは日常的にEmacsとEmacs Lispを利用しているユーザーが、Lispのどのような側面が「関数型」的で、なぜ関数型言語ではないと考えているのか、Emacsを用いたプログラミングの実践とEmacs Lispの「正体」までお話しします。
ClojureScript をベースとした軽量なコンパイラである Squint を用いて React による Web フロントエンド構築のノウハウを発表します。関数型言語で Web フロントエンドを構築してみたい方におすすめの発表です。
Squint は ClojureScript のビルドツールの新星です。ClojureScript の開発環境は時代とともに変化してきました。
もともと ClojureScript は Clojure (Java) 由来のビルドツールを使ってきましたが、 徐々に npm との親和性を求められるようになり、それを高めたツールが登場してきました。
その中でも Squint は npm ライブラリとして使用することができ、 package.json だけで ClojureScript ライクな言語を vite などと組み合わせて気楽にビルドすることができるツールです。
Squint を使うと TypeScript を導入するのと同じくらいの気楽さで ClojureScript を導入でき、 JavaScript 向けのライブラリをそのまま使うことができるので、 ClojureScript の文化を知らなくても開発を始められます。
従来の開発ではどうしても ClojureScript の独自文化を開発者が理解している必要がありましたが、 Squint ではそのハードルは大きく下がります。
今までの JavaScript の資産を気楽に使いつつ、関数型言語のパワフルさを活用する新しい Web フロントエンド開発手法を皆様にお伝えします。
Haskell では、 GHC 9.0 から -XLinearTypes
言語拡張が使えるようになり、線型型によるリソース管理に敏感な API を定義できるようになりました。
線型型は、Rust の所有権システムに類似した型システムであり、引数をきっかり一回消費する関数やデータ型を定義し、コンパイル時にリソースのリークがないか型検査によりチェックできるようになります。応用例は多くありますが、たとえば、純粋な可変配列や並列処理、use-after-free のないGC外アロケーション、Destination-Passing Style による効率的なデータ初期化、より型安全なストリーム処理、他言語とのリソースの安全な受け渡しなどがより型安全に行えるようになります。
本講演では、線型型が有効化された Haskell = Linear Haskell により新しくどのようなプログラムが書けるようになり、Haskell による実用的なソフトウェア開発でどのように役立つのかについて、時折 Rust と比較などしつつお話します。また、現在議論が行われている Linear Constraints や Zero-Copy Compact Regions が導入された場合、未来の Linear Haskell がどう変わっていくのかについても簡単に紹介したいと思います。
線型型、型理論、リソース管理、Linear Haskell、Haskell、Destination-Passing Style、Linear Constraints
※競技プログラミングの知識については必要ありません
(理論に近いかな?)
多くのアルゴリズムやデータ構造は、命令型プログラミングを前提に解説されていることが多いです。
アルゴリズム内部で使われるデータ構造は破壊的な変更が可能なことが前提であるため、短命データ構造が前提になります。また、プログラミング言語の抽象化能力には焦点を当てていないものが殆どで、Haskell のように、永続データ構造が備わっていて抽象化能力の高い言語でそのアルゴリズムを実装する場合、どのような抽象に至るのか解説されていることは希です。
私は競技プログラミングを Haskell で嗜んでおり、そのため様々なアルゴリズムを Haskell で実装しています。 Haskell でアルゴリズムを実装すると、その他の言語で実装したときには得られなかった様々なメンタルモデルでアルゴリズムを見ることができるようになり、結果、よりよい抽象に辿り着くことができることが多くあります。また、それをそのメンタルモデルそのままに実装することができるのも、関数型言語ならではと思っています。
例えば動的計画法を、代数的構造で抽象化することができます。 セグメント木はモノイドによって抽象化できることが知られていますが、Haskell ならそれをより自然な形で実装することができます。深さ優先探索や幅優先探索は、状態空間を宣言し、状態を遷移させる高階関数 f を渡すだけで様々な問題を解くことができるよう、実装することができます。よりよい抽象に至ると、より幅広い問題を一つの実装で解くことができます。
本セッションでは、幾つかのアルゴリズムの実装とその抽象を紹介し、命令型プログラミングと関数型プログラミングでの計算に対するメンタルモデルの違いを浮き彫りにすることを目標にします。