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
2.1k
Perlでも関数の型をチェックしたい
ybrliiu
February 18, 2021
Tweet
Share
More Decks by ybrliiu
See All by ybrliiu
これまでと、これからのPerlコミュニティ
ybrliiu
0
93
AstroNvim を使おう!
ybrliiu
0
2.8k
Perl5.32の新機能
ybrliiu
0
120
Vue.jsで作ったサイトをバニラJSで書き直す悲しいお話
ybrliiu
1
860
Perlにおける動的なモジュールロードのメリットとデメリット
ybrliiu
0
680
黒魔術で独自定義のenum型制約を満たす値のリ ストを取得する話
ybrliiu
0
300
Perlにおけるクラスの実装パターン.pdf
ybrliiu
0
1.3k
Presentation.pdf
ybrliiu
0
230
ぼくがPerlで開発を行う時に工夫していること
ybrliiu
0
420
Other Decks in Programming
See All in Programming
見た目から始める生産性向上
ikumatadokoro
7
830
今、知っておきたい! 生成AIエージェントの世界
elith
3
350
Ruby GitHub Packages
bkuhlmann
0
630
TYPO3 v13 – The road to LTS: What's new and new APIs
luisasofie_xoxo
0
200
GraphQLサーバの構成要素を整理する #ハッカー鮨 #tsukijigraphql / graphql server technology selection
izumin5210
4
830
Azure OpenAI Serviceのプロンプトエンジニアリング入門
tomokusaba
3
690
Rethinking UI building strategies @ SFI 2024
letelete
0
270
障害対応を起点としたもっといい開発と運用のサイクル作りのためにできること / Hatena Enginner Seminar #29
polamjag
0
120
Kotlin Multiplatform at Stable and Beyond (Android Makers 2024)
zsmb
0
100
Scalable Customer Journey Orchestration (CJO)
lewuathe
0
210
Zero Waste, Radical Magic, and Italian Graft – Quarkus Efficiency Secrets
hollycummins
0
230
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
270
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
221
21k
The MySQL Ecosystem @ GitHub 2015
samlambert
243
12k
Statistics for Hackers
jakevdp
789
220k
Fireside Chat
paigeccino
21
2.6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
116
18k
GraphQLの誤解/rethinking-graphql
sonatard
50
9.2k
Designing for Performance
lara
601
67k
No one is an island. Learnings from fostering a developers community.
thoeni
16
2.1k
Embracing the Ebb and Flow
colly
80
4.1k
Making the Leap to Tech Lead
cromwellryan
124
8.5k
What the flash - Photography Introduction
edds
64
11k
Visualization
eitanlees
136
14k
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?