haskell backpack 事始め

36
Haskell Backpack 事始め ひげ

Upload: nobutada-matsubara

Post on 29-Jan-2018

432 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Haskell Backpack 事始め

Haskell Backpack 事始めひげ

Page 2: Haskell Backpack 事始め

注意!

Page 3: Haskell Backpack 事始め

Backpack は2種類ある!Backpack'14:

Scott Kilpatrick 氏が提案(POPL 2014)

MixIn を利用して弱いモジュール言語に強いモジュール性を組み込む

Backpack'17:

Edward Z. Yang 氏が提案(彼の博士論文?)

既存の GHC に組み込めるように Backpack'14をリファクタリング

GHC8.2 や Cabal2.0 に組み込まれたのはコッチ

Page 4: Haskell Backpack 事始め

Backpack は2種類ある!どちらも目的は

Haskell に強いモジュール性を組み込むこと

しかし,ぼくの中でふたつの差分をしっかりと飲み込めてないので,イロイロと間違ってる部分がアルかもしれない....

Backpack'14の論文には概念的な主張が多いが,'17には少ない印象...'14の主張が,どこまで'17でも尊重されてるかハッキリとはまだ分からないので,その点が怪しいです...

Page 5: Haskell Backpack 事始め

ちなみに以下のリポジトリに少しだけまとめてある

matsubara0507/awesome-backpack - GitHub

今後も少しずつ更新してくつもり

Page 6: Haskell Backpack 事始め

本題

Page 7: Haskell Backpack 事始め

Haskell のモジュールは弱い

Page 8: Haskell Backpack 事始め

弱いモジュール性モジュール A がモジュール B に依存している場合

モジュール A の実装はモジュール B に依存する

Haskell の既存のモジュールシステム

Haskell の既存のパッケージシステム

は弱いモジュール性で実装されている

(インターフェースの依存性より弱いって意味っぽい)

Page 9: Haskell Backpack 事始め

強いモジュール性インターフェースの実装が何に依存しているかとは独立 にモジュールを型検査することが出来る.

(インターフェースの依存性より強いモジュール性)

結果として以下のことを可能にする!!

インターフェースとなるモジュール

リンクへのモジュールの再利用

モジュールの再帰的なリンク

しかし Haskell には弱いモジュールシステムしか...

Page 10: Haskell Backpack 事始め

そこで Backpack'14

Page 11: Haskell Backpack 事始め

Backpack'14パッケージレベルでの設計

シンプルな MixIn デザインを採用

ベースは MixML

いくつか問題があたので Haskell に対応させた

ジェネリックな設計なので他の Weak Module を持つ言語でも機能する(だろう)

強いモジュール性で Haskell を改造する!(Retrofit)

Page 12: Haskell Backpack 事始め

Modules in Today’s Haskell以下のような Haskell の Modules を考える

-- Socket.hsmodule Socket where data SocketT = ... open = ...

-- Server.hsmodule Server where import Socket data ServerT = ... SocketT ...

Page 13: Haskell Backpack 事始め

Packages in Backpack'14Backpack'14 だと次のように書ける

package complete-server where Socket = [ data SocketT = ... open = ... ] Server = [ import Socket data ServerT = ... SocketT ... ]

この時点では,ただまとめただけ...

※ ココの話はGHCに採用されては無い(構文とか)

Page 14: Haskell Backpack 事始め

Packages in Backpack'14Signature を利用すると次のように書ける

package partial-server where Socket :: [ data SocketT open :: Int -> SocketT ] Server = [ import Socket data ServerT = ... SocketT ... ]

※ ココの話はGHCに採用されては無い(構文とか)

Page 15: Haskell Backpack 事始め

Packages in Backpack'14packageを別々に定義してincludeすることもできる

package socketsig where Socket :: [ data SocketT open :: Int -> SocketT ]

package complete-server where include socketsig Server = [ import Socket data ServerT = ... SocketT ... ]

※ 以降の話はGHCに採用されては無い(構文とか)

Page 16: Haskell Backpack 事始め

Packages in Backpack'14Signature を持つパッケージに,それを実装したパッケージを linking する

package socketimpl where Socket = [ data SocketT = ... open = ... ]

package main where include partial-server include socketimpl

Page 17: Haskell Backpack 事始め

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 を与えて

Page 18: Haskell Backpack 事始め

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 ... ]

両方とも呼び出す!

Page 19: Haskell Backpack 事始め

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

Page 20: Haskell Backpack 事始め

しかし...Backpack'14 では GHC での実装

できなかった...

Page 21: Haskell Backpack 事始め

何故かBackpack'14 の意味論は Haskell の意味論と密接に結びついている

そのため,GHC と Cabal を切り離して実装することが出来なかった

Backpack'14 はコンパイラとパッケージマネージャー間の

抽象化の障壁 (abstraction barrier)

を壊してしまうらしい(用語が良く分からないけど)

Page 22: Haskell Backpack 事始め

そこで Backpack'17(そこでというか,そういうモチベーションだけどね...)

Page 23: Haskell Backpack 事始め

Backpack'17Backpack'14 を実用的に改良

コンパイラとパッケージマネージャーの障壁(バリア)を保持(??)

GHC8.2 と Cabal 2.0 に導入された

我らがヒーロー Stack 様はまだ

Hackage も 代わりに next.hackage

基本的な概念(MixIn, Signature など)はBackpack'14 と同じだと思われる...(構文は違うけど)

Page 24: Haskell Backpack 事始め

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 は複数書いて良い

Page 25: Haskell Backpack 事始め

例: 正規表現細かい実装は割愛...

-- regex.bkpunit 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

Page 26: Haskell Backpack 事始め

例: 正規表現-- regex.bkpunit 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 と打つだけ!

Page 27: Haskell Backpack 事始め

Cabal 2.0 で試す詳しくはこの記事を参照

1. bkp ファイルを unit ごとに分けて( *.hs と *.hsig )

2. cabal ファイルで依存関係を定義し

再構築するイメージ(たぶん)

さっきの例がこんな感じに分かれる.

Page 28: Haskell Backpack 事始め

大きく分けて2つのやり方Cabalのバージョンが 1.25 以上である必要がある

1. 単一のパッケージで管理する場合

このブランチやこのブランチ

cabal build でビルド

2. 分割してパッケージを管理する場合

このブランチ

cabal new-build でビルド

Page 29: Haskell Backpack 事始め

なぜ?Bcakpack パッケージをインスタンス化する必要があるためコマンドが(今のところ)異なる.

(1) は Cabal でビルドした時点で完全にカプセル化される.これは ghc --backpack でも同様である.

ちなみに

(1) であれば Stack と cabal-install でもビルド可能だそうだ.

Page 30: Haskell Backpack 事始め

まとめ

Page 31: Haskell Backpack 事始め

まとめHaskell に MixIn を用いた強いモジュール性を追加

モジュールの実装の依存を後から選択可能

モジュールをインターフェースとして使える

GHC8.2 から *.bkp で利用できる

Cabal2.0 から *.hsig *.hs *.cabal より *.bkp を構成

分けてにビルドするなら cabal new-build を使う

next.hackage で既に Backpack を用いたライブラリが管理されている

Page 32: Haskell Backpack 事始め

結局何がうれしいのか(ちゃんと論文読んでないので,ぼくが思うところ)

本質的には関係ない実装を利用者側で選択できる

A パッケージの文字列に Text を使うか ByteStringを使うかは利用者の自由

A-text とか A-bytestring とか別に作る必要が無い

型クラスに無理やり突っ込んでたモノが解決

モジュールレベルにアドホック多相(たぶん)

面白い

Page 33: Haskell Backpack 事始め

おまけ

Page 34: Haskell Backpack 事始め

Stack の現状...なんと1年前から Issue がある

IRCで議論してロードマップはできてるみたい

1. Stack が Cabal2.0 をサポート(済)

2. Stack をコンポーネントごとのビルドプランに切り替える(see haskell/cabal#2802)

一番エキサイティングらしい(?)

3. Cabal2.0前後でビルドプランを切り替える(難題)

Page 35: Haskell Backpack 事始め

つまりStack Project 単位でモジュール群を持っていた

しかし Backpack はモジュール(コンポーネント)ごとに管理する必要がある

従ってモジュール群の管理方法を変える事が必要

コレ曰く,インターナルライブラリをサポートするのが一つの方法で,foreign libraries で既に採用済みとのこと

最新のアクティビティがソレについてなので,その方向でやるのかな?

Page 36: Haskell Backpack 事始め

おしまい