<style>
.reveal, .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, "Microsoft JhengHei", Meiryo, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
text-transform: none !important;
}
.color-yellow{
color: yellow;
}
.alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
text-align: left;
padding: 10px 0;
}
.alert-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
.alert-success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.alert-danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
.reveal .slides span {
text-align: left;
display: inline-block;
}
p, li {
font-size: 0.88em !important;
}
li>p {
font-size: 1em !important;
}
</style>
# Package extensions<br>試してみた
[堀川 由人, ほりたみゅ, @Hyrodium](https://hyrodium.github.io/ja)
----
### おしながき
* 自己紹介
* Package extensionとは
* Package extension試してみた
* まとめ
---
## 自己紹介
Juliaのパッケージの開発やってます
* 自作パッケージ
* [BasicBSpline.jl](https://github.com/hyrodium/BasicBSpline.jl)
* [ImageClipboard.jl](https://github.com/hyrodium/ImageClipboard.jl)
* メンテナンス権限もらっているもの
* [FastGaussQuadrature.jl](https://github.com/JuliaApproximation/FastGaussQuadrature.jl)
* [Rotations.jl](https://github.com/JuliaGeometry/Rotations.jl)
* [IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl)
* [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl)
* [StaticArraysCore.jl](https://github.com/JuliaArrays/StaticArraysCore.jl)
* [Quaternions.jl](https://github.com/JuliaGeometry/Quaternions.jl)
* [Octonions.jl](https://github.com/JuliaGeometry/Octonions.jl)
---
## Package extensionsとは
* Julia v1.9から導入された新機能
* パッケージのロード時間削減に役立つ
* Juliaパッケージにおける2種類の依存関係
* Strong dependency (`PkgA` → `PkgB`)
* `PkgA`内の機能で`PkgB.func_b`を使っている
* Weak dependency (`PkgA` → `PkgC`)
* `PkgA`内で`func_a(::PkgC.TypeC)`を定義している
* `using PkgA`
* `PkgB`もロードされるが、`PkgC`のロードは必須でない
* `using PkgA, PkgC`
* `func_a(::TypeC)`の定義もロードしたい
これを実現するのがPackage extensions
----
### Package extensionsの導入方法
概要
* 拡張メソッドを別ファイルのモジュールで管理
* モジュールのメタデータを`Project.toml`で管理
導入方法
* `Project.toml`の`[weakdeps]`セクションの編集
* weak dependenciesを追加
* `Project.toml`の`[extensions]`セクションの編集
* weakdepsに対応するモジュールの指定
* モジュール名は`"PkgAPkgCExt"`
* 拡張メソッドの定義
* `PkgA/ext/PkgAPkgCExt.jl`内の
* `PkgAPkgCExt`モジュールに拡張メソッドを記述
----
### 補足: `Project.toml`とは
Juliaパッケージの依存関係などを定義するファイル
```
name = "MyPkgA"
uuid = "eb62ad0d-c07c-4140-a83b-b6ff560c525f"
authors = ["hyrodium <hyrodium@gmail.com>"]
version = "0.1.0"
[deps]
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
[compat]
IntervalSets = "0.5, 0.6, 0.7"
```
Julia v1.9で新たに以下のセクションが追加された
* `[weakdeps]`
* `[extensions]`
---
### Package extensions試してみた
[BasicBSpline.jl](https://github.com/hyrodium/BasicBSpline.jl)で試しました
weakdepsとして管理するパッケージ:
* `ChainRulesCore`
* 微分則を定義するパッケージ
* `RecipesBase`
* Plots.jlでのプロット方法を書くパッケージ
[BasicBSpline.jl PR#334](https://github.com/hyrodium/BasicBSpline.jl/pull/334/files)
----
### ちょっと詰まったところ
* 既存の`[deps]`はstrong dependenciesではない
* weakとstrongを合わせたもの
* つまり`[weakdeps]`に書いたものを削除しない
* [Aqua.jl](https://github.com/JuliaTesting/Aqua.jl)の`Project.toml`フォーマッティング
* v1.6とv1.9で自動フォーマッティングの形式が異なる
* v1.9のみでAquaのテストを走らせるように変更
* Julia v1.6 (LTS)のサポート
* 古いJuliaでは`[weakdeps]`は無視されるだけ
* 以下のように拡張メソッドを読み込む
```julia
if !isdefined(Base, :get_extension)
include("../ext/PlottingContourExt.jl")
end
```
[公式ドキュメント](https://pkgdocs.julialang.org/v1.9/creating-packages/#Transition-from-normal-dependency-to-extension)
----
### 疑問点
- PkgA.jlとPkgB.jlがそれぞれ`func_a`と`TypeB`を定義している
- PkgAとPkgBの間には依存関係が無い
- MyPkg.jlで`func_a(::TypeB, ::MyPkg.MyType)`を定義したい
このとき、「PkgAとPkgBが同時に読み込まれたときにだけロードされるようなextensions」は作れるか?
---
## まとめ
```julia
julia> @time_imports using BasicBSpline
29.0 ms IntervalSets
3.2 ms StaticArraysCore
441.4 ms StaticArrays
12.7 ms Preferences
0.3 ms PrecompileTools
13.9 ms RecipesBase
0.3 ms Compat
0.1 ms Compat → CompatLinearAlgebraExt
24.8 ms ChainRulesCore
8.9 ms BasicBSpline
```
Package extensionsでロード時間高速化!
```julia
julia> @time_imports using BasicBSpline
35.4 ms IntervalSets
2.6 ms StaticArraysCore
440.6 ms StaticArrays
8.7 ms BasicBSpline
```
---
## 参考文献
- [公式ドキュメント](https://pkgdocs.julialang.org/v1.9/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions))
- [IntervalSets.jlでのPR例](https://github.com/JuliaMath/IntervalSets.jl/pull/146)
- [JuliaCon2023での解説](https://www.youtube.com/watch?v=TiIZlQhFzyk)
- [BasicBSpline.jlでのスクラップ](https://zenn.dev/hyrodium/scraps/f04f6bb939cc4f)
{"breaks":true,"lang":"ja","dir":"ltr","robots":"noindex, nofollow","slideOptions":"{\"theme\":\"white\",\"transition\":\"slide\"}","description":"堀川 由人, ほりたみゅ, @Hyrodium","title":"JuliaTokai #16 (2023/10/01) - b","contributors":"[{\"id\":\"41421433-16a1-4a57-ac11-6f7b7becb765\",\"add\":8674,\"del\":3621}]"}