SlideShare a Scribd company logo
1 of 36
Download to read offline
Haskell Backpack 事始め
ひげ
注意!
Backpack は2種類ある!
Backpack'14:
Scott Kilpatrick 氏が提案(POPL 2014)
MixIn を利用して弱いモジュール言語に強いモ
ジュール性を組み込む
Backpack'17:
Edward Z. Yang 氏が提案(彼の博士論文?)
既存の GHC に組み込めるように Backpack'14
をリファクタリング
GHC8.2 や Cabal2.0 に組み込まれたのはコッチ
Backpack は2種類ある!
どちらも目的は
Haskell に強いモジュール性を組み込むこと
しかし,ぼくの中でふたつの差分をしっかりと飲み込
めてないので,イロイロと間違ってる部分がアルかも
しれない....
Backpack'14の論文には概念的な主張が多いが,'17
には少ない印象...
'14の主張が,どこまで'17でも尊重されてるかハッキ
リとはまだ分からないので,その点が怪しいです...
ちなみに
以下のリポジトリに少しだけまとめてある
matsubara0507/awesome-backpack - GitHub
今後も少しずつ更新してくつもり
本題
Haskell のモジュールは弱い
弱いモジュール性
モジュール A がモジュール B に依存している場合
モジュール A の実装はモジュール B に依存する
Haskell の既存のモジュールシステム
Haskell の既存のパッケージシステム
は弱いモジュール性で実装されている
(インターフェースの依存性より弱いって意味っぽい)
強いモジュール性
インターフェースの実装が何に依存しているかとは
独立 にモジュールを型検査することが出来る.
(インターフェースの依存性より強いモジュール性)
結果として以下のことを可能にする!!
インターフェースとなるモジュール
リンクへのモジュールの再利用
モジュールの再帰的なリンク
しかし Haskell には弱いモジュールシステムしか...
そこで Backpack'14
Backpack'14
パッケージレベルでの設計
シンプルな MixIn デザインを採用
ベースは MixML
いくつか問題があたので Haskell に対応させた
ジェネリックな設計なので他の Weak Module を
持つ言語でも機能する(だろう)
強いモジュール性で Haskell を改造する!(Retrofit)
Modules in Today’s Haskell
以下のような Haskell の Modules を考える
-- Socket.hs
module Socket where
data SocketT = ...
open = ...
-- Server.hs
module Server where
import Socket
data ServerT = ... SocketT ...
Packages in Backpack'14
Backpack'14 だと次のように書ける
package complete-server where
Socket = [
data SocketT = ...
open = ...
]
Server = [
import Socket
data ServerT = ... SocketT ...
]
この時点では,ただまとめただけ...
※ ココの話はGHCに採用されては無い(構文とか)
Packages in Backpack'14
Signature を利用すると次のように書ける
package partial-server where
Socket :: [
data SocketT
open :: Int -> SocketT
]
Server = [
import Socket
data ServerT = ... SocketT ...
]
※ ココの話はGHCに採用されては無い(構文とか)
Packages in Backpack'14
packageを別々に定義してincludeすることもできる
package socketsig where
Socket :: [
data SocketT
open :: Int -> SocketT
]
package complete-server where
include socketsig
Server = [
import Socket
data ServerT = ... SocketT ...
]
※ 以降の話はGHCに採用されては無い(構文とか)
Packages in Backpack'14
Signature を持つパッケージに,それを実装したパッ
ケージを linking する
package socketimpl where
Socket = [
data SocketT = ...
open = ...
]
package main where
include partial-server
include socketimpl
Packages in Backpack'14
再利用する
package server-linked-1 where
include partial-server
include socketimpl-1
package server-linked-2 where
include partial-server
include socketimpl-2
別々の実装 socketimplN を与えて
Packages in Backpack'14
再利用する
package multi where
A = { include server-linked-1 }
B = { include server-linked-2 }
Main = [
import qualified A.Server
import qualified B.Server
...
]
両方とも呼び出す!
Packages in Backpack'14
再帰的にも適用できちゃう!
package ab-sigs where
A :: [ S_A ]
B :: [ S_B ]
package b-from-a where
include ab-sigs
B = [ inport A ; ... ]
package a-from-b where
include ab-sigs
A = [ inport B ; ... ]
package ab-rec-sep where
include a-form-b
include b-form-a
しかし...
Backpack'14 では GHC での実装
できなかった...
何故か
Backpack'14 の意味論は Haskell の意味論と密接
に結びついている
そのため,GHC と Cabal を切り離して実装するこ
とが出来なかった
Backpack'14 は
コンパイラとパッケージマネージャー間の
抽象化の障壁 (abstraction barrier)
を壊してしまうらしい(用語が良く分からないけど)
そこで Backpack'17
(そこでというか,そういうモチベーションだけどね...)
Backpack'17
Backpack'14 を実用的に改良
コンパイラとパッケージマネージャーの障壁(バリ
ア)を保持(??)
GHC8.2 と Cabal 2.0 に導入された
我らがヒーロー Stack 様はまだ
Hackage も 代わりに next.hackage
基本的な概念(MixIn, Signature など)は
Backpack'14 と同じだと思われる...(構文は違うけど)
GHC 8.2 で試す
詳しくはこの記事を参照
1. *.bkp というファイルを作る
2. ghc --backpack xxx.bkp と打つだけ
*.bkp は *.hs に比べて unit と言う階層ができた
unit main where
module Main where
main = putStrLn "Hello world!"
ひとつの *.bkp ファイルに unit は複数書いて良い
例: 正規表現
細かい実装は割愛...
-- regex.bkp
unit str-bytestring where
module Str
unit str-string where
module Str
unit regex-types where
module Regex.Types
unit regex-indef where
dependency regex-types
signature Str
module Regex
例: 正規表現
-- regex.bkp
unit main where
dependency regex-types
dependency
regex-indef[Str=str-string:Str]
(Regex as Regex.String)
dependency
regex-indef[Str=str-bytestring:Str]
(Regex as Regex.ByteString)
module Main
ひとつのインターフェースモジュールで別々の実装(
String と ByteString ) が同時に使える!
後は ghc --backpack regex.bkp と打つだけ!
Cabal 2.0 で試す
詳しくはこの記事を参照
1. bkp ファイルを unit ごとに分けて( *.hs と *.hsig )
2. cabal ファイルで依存関係を定義し
再構築するイメージ(たぶん)
さっきの例がこんな感じに分かれる.
大きく分けて2つのやり方
Cabalのバージョンが 1.25 以上である必要がある
1. 単一のパッケージで管理する場合
このブランチやこのブランチ
cabal build でビルド
2. 分割してパッケージを管理する場合
このブランチ
cabal new-build でビルド
なぜ?
Bcakpack パッケージをインスタンス化する必要があ
るためコマンドが(今のところ)異なる.
(1) は Cabal でビルドした時点で完全にカプセル化さ
れる.
これは ghc --backpack でも同様である.
ちなみに
(1) であれば Stack と cabal-install でもビルド可能だ
そうだ.
まとめ
まとめ
Haskell に MixIn を用いた強いモジュール性を追加
モジュールの実装の依存を後から選択可能
モジュールをインターフェースとして使える
GHC8.2 から *.bkp で利用できる
Cabal2.0 から *.hsig *.hs *.cabal より *.bkp を構成
分けてにビルドするなら cabal new-build を使う
next.hackage で既に Backpack を用いたライブラ
リが管理されている
結局何がうれしいのか
(ちゃんと論文読んでないので,ぼくが思うところ)
本質的には関係ない実装を利用者側で選択できる
A パッケージの文字列に Text を使うか ByteString
を使うかは利用者の自由
A-text とか A-bytestring とか別に作る必要が無い
型クラスに無理やり突っ込んでたモノが解決
モジュールレベルにアドホック多相(たぶん)
面白い
おまけ
Stack の現状...
なんと1年前から Issue がある
IRCで議論してロードマップはできてるみたい
1. Stack が Cabal2.0 をサポート(済)
2. Stack をコンポーネントごとのビルドプランに切
り替える(see haskell/cabal#2802)
一番エキサイティングらしい(?)
3. Cabal2.0前後でビルドプランを切り替える(難題)
つまり
Stack Project 単位でモジュール群を持っていた
しかし Backpack はモジュール(コンポーネント)ご
とに管理する必要がある
従ってモジュール群の管理方法を変える事が必要
コレ曰く,インターナルライブラリをサポートするの
が一つの方法で,foreign libraries で既に採用済みと
のこと
最新のアクティビティがソレについてなので,その方
向でやるのかな?
おしまい

More Related Content

More from Nobutada Matsubara

More from Nobutada Matsubara (20)

Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側Haskell で作る競技型イベントの裏側
Haskell で作る競技型イベントの裏側
 
Marp Next Theme: Colors
Marp Next Theme: ColorsMarp Next Theme: Colors
Marp Next Theme: Colors
 
Marp Next Tips !
Marp Next Tips !Marp Next Tips !
Marp Next Tips !
 
Haskell で CLI
Haskell で CLIHaskell で CLI
Haskell で CLI
 
貧者のための「cron」
貧者のための「cron」貧者のための「cron」
貧者のための「cron」
 
Build Dockferile with Haskell
Build Dockferile with HaskellBuild Dockferile with Haskell
Build Dockferile with Haskell
 
Elixir Programming with Type checking
Elixir Programming with Type checkingElixir Programming with Type checking
Elixir Programming with Type checking
 
MixML 作ってみる
MixML 作ってみるMixML 作ってみる
MixML 作ってみる
 
Elm でなんかつくる
Elm でなんかつくるElm でなんかつくる
Elm でなんかつくる
 
Haskell と Elm と JSON の話
Haskell と Elm と JSON の話Haskell と Elm と JSON の話
Haskell と Elm と JSON の話
 
GitHub での Haskell の色が変わったんで
GitHub での Haskell の色が変わったんでGitHub での Haskell の色が変わったんで
GitHub での Haskell の色が変わったんで
 
日記って続かないよね...
日記って続かないよね...日記って続かないよね...
日記って続かないよね...
 
Lisper はじめました (再)
Lisper はじめました (再)Lisper はじめました (再)
Lisper はじめました (再)
 
Marp colors
Marp colorsMarp colors
Marp colors
 
Marp Tips
Marp TipsMarp Tips
Marp Tips
 
Whitespcae 入門
Whitespcae 入門Whitespcae 入門
Whitespcae 入門
 
入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !
 
SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成SKIコンビネーターによる処理系の作成
SKIコンビネーターによる処理系の作成
 
Ruby4Ctf
Ruby4CtfRuby4Ctf
Ruby4Ctf
 
Lisper はじめました(大嘘)
Lisper はじめました(大嘘)Lisper はじめました(大嘘)
Lisper はじめました(大嘘)
 

Haskell Backpack 事始め