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
CSC509 Lecture 04
javiergs
PRO
0
300
NixOS + Kubernetesで構築する自宅サーバーのすべて
ichi_h3
0
730
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
200
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で
koxya
1
1.3k
Goで実践するドメイン駆動開発 AIと歩み始めた新規プロダクト開発の現在地
imkaoru
4
830
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
490
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
1k
TFLintカスタムプラグインで始める Terraformコード品質管理
bells17
2
160
20251016_Rails News ~Rails 8.1の足音を聴く~
morimorihoge
1
120
bootcamp2025_バックエンド研修_WebAPIサーバ作成.pdf
geniee_inc
0
100
Web Components で実現する Hotwire とフロントエンドフレームワークの橋渡し / Bridging with Web Components
da1chi
3
2.3k
(Extension DC 2025) Actor境界を越える技術
teamhimeh
1
250
Featured
See All Featured
Unsuck your backbone
ammeep
671
58k
Optimizing for Happiness
mojombo
379
70k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Six Lessons from altMBA
skipperchong
28
4k
How to Ace a Technical Interview
jacobian
280
24k
Done Done
chrislema
185
16k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
900
jQuery: Nuts, Bolts and Bling
dougneiner
65
7.9k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
980
Raft: Consensus for Rubyists
vanstee
139
7.1k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.7k
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?