ElixirはErlang VM (BEAM) の上で動作するRubyライクは文法をもつ関数型言語として知られています。
Erlangと同様に値は全てイミュータブルですが、Erlangが再束縛(再代入)不可である一方、Elixirは再束縛(再代入)可という異なるアプローチを採用しています。
再束縛(再代入)の可否を選択できる言語においては、正当な理由がない限り再束縛(再代入)不可の利用が推奨されており、Elixirのアプローチは一見悪手のように見えるかもしれません。
なぜElixirの再束縛(再代入)可という選択が悪くない戦略なのかについて、関数型言語の特性や、束縛、代入、ミュータブル、イミュータブル等の整理を通じて紐解いてみたいと思います。
昨今巷で Effect システムが流行っていますが、実はその双対、Coeffect システムというものがあるのをご存じでしょうか。
Effect が関数のボディでの作用について述べるシステムだとすれば、Coeffect は対称的に、引数の性質について述べるシステムです。変数の使用回数のトラッキング、セキュリティレベルの追跡などがそのインスタンスになることが知られています。
Effect システムについても軽く説明しますが、型付きラムダ計算等の知識は前提とします。
「関数型プログラミング」や「関数型言語」の定義に普遍の共通認識は存在しませんが、複数の(いわゆる)関数型言語にしばらく触れてみると、共通して重視されている概念や考え方、設計パターン、機能と思われるものも見えてきます。
Haskell, Scala, Clojure, Elixirという性質の異なる4つの関数型言語での特徴的なプログラミングスタイルを吟味(= テイスティング)してみることを通して、関数型プログラミングの中核にありそうなもの、周辺にありそうなもの、(直接的には)無関係そうなものについて一緒に考えてみましょう🍷
取り上げる(かもしれない)キーワード: 関数とその組み合わせ方いろいろ, 変換 vs 命令, 式指向 vs 文指向(cf. コードの形), よくある設計パターン/言語機能, 参照透過性, 不変性と永続性, 合成可能性, データ指向 vs オブジェクト指向, 再利用性と抽象度(cf. 命名), メタプログラミングと言語処理系, 関数型プログラマのメンタルモデル
関数型プログラミングの基本ってラムダ計算とよく言われます。そもそもラムダ計算って何でしょう?コンピュータの計算理論の一つですが、あまり有名ではありません。関数型プログラミング言語の基本的なイメージをつかめるように、初心者にも分かるようにラムダ計算を紹介したいと思います。ラムダ計算についてまだ学んででいない人にも、学んだけれど忘れた人にも、導入として聞いてもらいたいです。
関数型プログラミングと聞いて、初心者の方が一番に連想するキーワードは"純粋関数"ではないでしょうか。
一方で、純粋関数を作るうえで"副作用を受けない・スコープが決まっている値"というのは非常に重要ですが、この概念=代数的データ型についてはまだそれほど広まっていないように思います(主観)
そこで、このセッションではKotlinを用いて直積型と直和型から始まり、enumとSealed classとの違いについてまでお話しします。
並列分散処理は高いスケーラビリティを求められる一方で、タスク分割・通信制御・データ整合性など管理するべきことが多く、とにかく開発が複雑になりがちな領域です。
そういった課題に対し、アクターモデルはソフトウェアを「アクター」という小さなメッセージ駆動単位に分割することで、スケーラブルかつ扱いやすい計算モデルを提供します。
さらにアクター間のメッセージに静的な型を付けることで、不正な通信をコンパイル時に防ぐことができます。
トヨタ自動車では、Scalaの型付きアクターモデルライブラリPekkoを基盤として、人流シミュレータ・交通シミュレータ・ドライビングシミュレータ・VRなどをリアルタイムに連携する分散メッセージングフレームワークArkTwinをOSSとして開発しています。
ArkTwinでは大量の時空情報を低遅延で処理する必要があり、型付きアクターモデルの恩恵なしには実現できませんでした。
本セッションでは、ArkTwinの開発を通じて得られた知見をもとに型付きアクターモデルの利点と実装パターンについて紹介し、それらがもたらす分散シミュレーションの未来像についてお話します。
JVM系で関数型プログラミングと聞くと真っ先に思い浮かぶのがScalaだと思います。
ですが、僕はJVM系言語だとKotlinが大好きです。シンプルな文法だけど表現力が豊かなところ。初歩の学習コストが低く済むところ。Null Safetyなところ。Javaと互換性があるところ…枚挙に暇がありません。
そんなKotlinを使うと、Scalaでなくとも十分満足に関数型プログラミングに取り組むことができます。
このセッションでは、
などに触れながら「Kotlinでも(十分満足に)関数型プログラミングができる!」というお話をさせていただこうと思います。
なるべく Beginner から Advanced まで対象と出来るよう努力します。タイトルを聞いて何かしら感情が動いた方であればおすすめです。
「Haskellは純粋関数型言語だから副作用がないらしいけど、入出力処理などはどうやるんだろう?」というような疑問を抱えている方は多いでしょう。本発表ではHaskellの歴史と現状を顧みて、そのような疑問が生まれる背景や、「Haskellは副作用がない」と考えることの問題点と、それを踏まえて「副作用があるHaskell」という認識が普及した未来について論じます。関数型プログラミングやHaskellを学習する際ありがちな「思考の憑きもの」を祓う発表になれば幸いです。
2018年にver.1.0がリリースされた新言語 Julia について、自己の経緯をベースに関数型プログラミング(以降 FP と略記)の観点で紹介・解説します。
Julia はマルチパラダイムを謳っており、特別 FP に特化した言語というわけではありません。所謂『関数型言語』と呼ばれる他言語にはよくあるけれど Julia にはない機能・言語仕様もあります。一方で、動的言語でありながら構造的に設計された型システムを持ち、多重ディスパッチという機構とそこから導かれる強力なポリモーフィズム、また
Lisp 由来の『真のマクロ』などのメタプログラミング機構を持っています。その辺りを足がかりに、以下のような内容について紹介・解説します。
関数型プログラミングに始めて触れる方にスキルを身につける/教えるためのトレーニング方法について紹介します。
私の所属先では、サーバサイドの言語として以前は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 を渡すだけで様々な問題を解くことができるよう、実装することができます。よりよい抽象に至ると、より幅広い問題を一つの実装で解くことができます。
本セッションでは、幾つかのアルゴリズムの実装とその抽象を紹介し、命令型プログラミングと関数型プログラミングでの計算に対するメンタルモデルの違いを浮き彫りにすることを目標にします。