Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perlでも関数の型をチェックしたい
Search
ybrliiu
February 18, 2021
Programming
0
3.3k
Perlでも関数の型をチェックしたい
ybrliiu
February 18, 2021
Tweet
Share
More Decks by ybrliiu
See All by ybrliiu
これまでと、これからのPerlコミュニティ
ybrliiu
0
160
AstroNvim を使おう!
ybrliiu
0
4.7k
Perl5.32の新機能
ybrliiu
0
160
Vue.jsで作ったサイトをバニラJSで書き直す悲しいお話
ybrliiu
1
1.1k
Perlにおける動的なモジュールロードのメリットとデメリット
ybrliiu
0
870
黒魔術で独自定義のenum型制約を満たす値のリ ストを取得する話
ybrliiu
0
420
Perlにおけるクラスの実装パターン.pdf
ybrliiu
0
1.6k
Presentation.pdf
ybrliiu
0
270
ぼくがPerlで開発を行う時に工夫していること
ybrliiu
0
550
Other Decks in Programming
See All in Programming
クラシルを支える技術と組織
rakutek
0
200
理論と実務のギャップを超える
eycjur
0
120
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で
koxya
1
1.2k
CSC509 Lecture 01
javiergs
PRO
1
440
その面倒な作業、「Dart」にやらせませんか? Flutter開発者のための業務効率化
yordgenome03
0
110
Signals & Resource API in Angular: 3 Effective Rules for Your Architecture @BASTA 2025 in Mainz
manfredsteyer
PRO
0
110
複雑化したリポジトリをなんとかした話 pipenvからuvによるモノレポ構成への移行
satoshi256kbyte
1
990
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
520
Go言語の特性を活かした公式MCP SDKの設計
hond0413
1
210
CSC305 Lecture 01
javiergs
PRO
1
400
育てるアーキテクチャ:戦い抜くPythonマイクロサービスの設計と進化戦略
fujidomoe
1
170
Building, Deploying, and Monitoring Ruby Web Applications with Falcon (Kaigi on Rails 2025)
ioquatix
4
1.8k
Featured
See All Featured
It's Worth the Effort
3n
187
28k
Site-Speed That Sticks
csswizardry
11
890
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Automating Front-end Workflow
addyosmani
1371
200k
Designing for Performance
lara
610
69k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Speed Design
sergeychernyshev
32
1.1k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
19
1.2k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
53k
Music & Morning Musume
bryan
46
6.8k
Transcript
Perl でも関数の型をチェックしたい Japan.pm 2021 id: ybrliiu
自己紹介 • id: _ybrliiu / mp0liiu • 所属 : 株式会社モバイルファクトリー
• 普段はPerl書いています • 最近は古くなったフロントエンドの エコシステムをアップデートする仕事をしています
突然ですが 次のコードを見てどう思いますか?
None
インスタンス変数の型に サブルーチンリファレンスの型を指定
コールバックに渡される引数、 期待する返り値が何なのかわからん!
期待していないような値を返す コールバックが渡されたらどうしよう?
コールバック関数に型がついてほしい
このようになってほしい
このようになってほしい コールバックに渡される引数、 期待する返り値が明示されている
Perlにおける型制約事情 • 動的型付け言語なので型チェックは動的に行われる • 外部にインターフェースを公開する部分はしばしば型チェックが行われて いる ◦ インスタンス変数や関数の引数の型など ◦ 型制約を設けることによるメリットが多い
具体例 1. クラスビルダーによる型チェック 2. 引数バリデーターによる型チェック 3. 型制約ライブラリ
クラスビルダーによる型チェック • クラスビルダー ◦ オブジェクト指向関連の実装を簡単に記述できるライブラリ ◦ e.g.) C::A::L, Moose, Mouse,
Dios, Zydeco, etc... • 組み込みで型制約システムを持っているクラスビルダーがある • アトリビュートを作るとインスタンス変数の型をチェックしてくれる
Mooseによるインスタンス変数の型チェックの例
引数バリデーターによる型チェック • CPAN には引数をチェックする様々なモジュールがある ◦ e.g.) Params::Validate, Data::Validator, Smart::Args, Type::Params,
Function::Parameters etc... • クラスビルダー組み込みの型制約システムや、型制約ライブラリと組 み合わせて使うことで引数の型をチェックできる
Smart::Args による引数の型チェックの例
型制約ライブラリ • 型チェックする機能だけを提供するモジュール ◦ e.g.) Type::Tiny, Specio • 再利用性が高い •
最近は Type::Tiny とクラスビルダーや引数バリデーターと組み合わ せて使うことがトレンド • 同梱の Types::Standard で提供されている型でほとんどのユース ケースをカバーできる
Type::Tiny による型チェックの例
Perlの関数型の現状 • どの型制約ライブラリやクラスビルダーを探しても、コードリファレンス であるかをチェックする CodeRef 型しか存在しない • 関数の引数の型や返り値の型をチェック / 明示したくてもできない
◦ 他の型をしっかり書いていても関数の部分だけ割れ窓になる
ないなら実装するぞ!!!
実装するにあたって必要なもの • 関数の型情報を付与 / 取得できる仕組み • 2つの関数の型情報を比較する仕組み • 関数の型情報を比較する型
関数の型情報を付与 / 取得できる仕組みへの要求 • CodeRef の引数の型と返り値の型情報を付与し、それらをチェックす る • 後から引数の型と返り値の型情報を取得できるようにする •
引数の型と返り値の型情報は CodeRef のスコープが外れたら破棄 して欲しい • 実行時のオーバーヘッドをなるべく減らしたい
Sub::WrapInType の実装 • 前述の要求を満たすものがなかったので実装 • wrap_sub 関数に CodeRef、引数の型、返り値の型を与えると、与え られた CodeRef
を引数の型と返り値の型をチェックする処理でラップ したCodeRefを返す
Sub::WrapInType の利用例
• wrap_sub で生成される CodeRef は bless されたオブジェクト ◦ 関数の型の情報はスコープが外れたら破棄される ◦
CodeRef をそのまま実行できる ▪ ハッシュベースのクラスで演算子オーバーロードする場合と比 べてコード実行時のオーバーヘッドが少ない • Inside-out object というテクニックでクラスを実装 Sub::WrapInType の実装
実装するにあたって必要なもの • 関数の型情報を付与 / 取得できる仕組み • 2つの関数の型情報を比較する仕組み • 関数の型情報を比較する型
2つの関数の型情報を比較する仕組み Sub::Meta を利用する
実装するにあたって必要なもの • 関数の型情報を付与 / 取得できる仕組み • 2つの関数の型情報を比較する仕組み • 関数の型情報を比較する型
関数の型情報を比較する型の実装 • Sub::WrapInType で関数の型の情報を付与した CodeRef を Sub::Meta で比較する型を実装する • ポータビリティを考慮し
Type::Tiny で型を実装する ◦ 様々なクラスビルダーや引数バリデーターと組み合わせて利用で きる
Type::Tiny での独自型の実装 • Type::Tiny のコンストラクタに値をチェックする処理、親にあたる型、 型名、型強制する場合の処理などを渡して実装する ◦ Type::Utils のユーティリティ関数を用いれば簡単 •
型オブジェクトを返す関数を作ってエクスポートする ◦ Type::Library を利用すると簡単
Type::Tiny での独自型の実装例
総称型 • 関数の型情報を比較する型は関数の型情報をパラメータにとる総称 型になる • 総称型とは ◦ 抽象化された型で、型パラメータを渡すと具体化する ◦ Type::Tiny
でいう ArrayRef[T], HashRef[T] など
Type::Tiny での総称型の実装 • 独自の総称型を簡単に実装できるユーティリティは存在しない • 型パラメータが渡されたとき型名、型制約、型強制がどのように具体化 されるかを定義する ◦ name_generator, constraint_generator,
coercion_generator • 上記のパラメータを Type::Tiny に渡してインスタンスを生成 • 型パラメータリストを ArrayRef で取り型を具体化する関数を作る
Type::Tiny での総称型の実装例
Type::Tiny での総称型の実装例
Type::Tiny での総称型の実装例
実装するにあたって必要なもの • 関数の型情報を付与 / 取得できる仕組み • 2つの関数の型情報を比較する仕組み • 関数の型情報を比較する型
関数の型をチェックする型 Types::TypedCodeRef が完成!
Perlで関数の型チェックを実現
この型を使って最初のコードを書き換え てみましょう
None
どんなコールバック関数を渡せばいいかひ と目でわかる!!!
型強制もできる
型強制もできる CodeRef を渡すと Types::TypedCodeRef の型情報を使い Sub::WrapInType でラップしてくれる
DEMO
今後の展望 • inline 化してパフォーマンス良くしたい ◦ 型チェックするコードを文字列化して結合し eval することで、関数 呼び出しのオーバーヘッドがなくなる •
エラーメッセージをわかりやすくしたい ◦ 現状急に「型チェックに失敗した!」みたいなエラーがでてくるの で何が原因でエラーになったのかわかりにくい
まとめ
Types::TypedCodeRef で コールバックの型をつけよう!
Any Questions?