Holy Traits 入門 === <!-- .element: style="font-size:340%" --> <!-- .slide: data-background-color="rgba(102,130,223,0.3)" --> 2020/02/08 JuliaTokai \#05 antimon2(後藤 俊介) Note: Julia で機能の Mix-in っ! ---- <!-- .slide: data-background-color="rgba(102,130,223,0.3)" --> ## お品書き + お前誰よ? + 簡単なJuliaの紹介 + Holy Traits Pattern --- <!-- .slide: data-background-color="rgba(102,130,223,0.3)" --> # お前誰よ? ---- <!-- .slide: data-background-color="rgba(102,130,223,0.3)" --> ## 自己紹介 + 名前:後藤 俊介 + 所属:**[有限会社 来栖川電算](https://www.kurusugawa.jp)** + コミュニティ:**[JuliaTokai](https://juliatokai.connpass.com/)**, **[機械学習名古屋](https://machine-learning.connpass.com/)**, [Python東海](https://connpass.com/series/292/), Ruby東海, … + 言語:**[Julia](https://julialang.org)**, Python, Scala(勉強中), Ruby, … + ![Twitter](https://i.imgur.com/HqouMIg.png)<!-- .element: class="plain" style="vertical-align:middle;background:transparent" --> [@antimon2](https://twitter.com/antimon2) / ![Facebook](https://i.imgur.com/01nPd37.png)<!-- .element: class="plain" style="vertical-align:middle;background:transparent" --> [antimon2](https://www.facebook.com/antimon2) + ![Github](https://i.imgur.com/yBKtii5.png)<!-- .element: class="plain" style="vertical-align:middle;background:transparent" --> [antimon2](https://github.com/antimon2/) / ![Qiita](https://i.imgur.com/FxHMi64.png)<!-- .element: class="plain" style="vertical-align:middle;background:transparent" --> [@antimon2](http://qiita.com/antimon2) / [<i class="fa fa-file-text"><!-- .element style="font-size:120%" --></i> @antimon2](https://hackmd.io/@antimon2) Note: 今日は(も?)大っぴらに Julia の話ができるっ ---- <!-- .slide: data-background-color="rgba(44,214,221,0.3)" --> [![有限会社来栖川電算](https://i.imgur.com/8Kuhfel.png) https://www.kurusugawa.jp](https://www.kurusugawa.jp) Note: 普段は Python で仕事してますっ ---- <!-- .slide: data-background-color="rgba(204,102,51,0.3)" --> [![Python東海 第41回勉強会](https://i.imgur.com/3V0MIbW.png) https://connpass.com/event/165645/](https://connpass.com/event/165645/) Note: ちょうど1ヶ月後に開催! 今回は会場提供! ---- <!-- .slide: data-background-color="rgba(204,102,51,0.3)" --> [![機械学習名古屋 第22回勉強会 AnnoFab ハンズオン](https://i.imgur.com/XMwOQgn.png) https://machine-learning.connpass.com/event/148266/](https://machine-learning.connpass.com/event/148266/) Note: 次回開催未定なので取り敢えず、前々回の情報! --- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> # <small>簡単な</small><br>Julia の紹介 Note: Julia の紹介っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> [![Julia](https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.svg?sanitize=true)<!-- .element: style="background:white;width:80%" -->](https://julialang.org) Note: 実は何気にロゴマイナーチェンジしてますっ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## Julia とは?(1) + [The Julia Language](https://julialang.org) + 最新 v1.3.1(2019/12/30) + LTS v1.0.5(2019/09/09) + pre v1.4.0-rc1(2020/01/23) + 科学技術計算に強い! + 動作が速い!(LLVM JIT コンパイル) Note: ググるときはなるべく [julialang](https://www.google.co.jp/search?q=julialang) で! ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## Julia とは?(2) > + Rのように中身がぐちゃぐちゃでなく、 > + Rubyのように遅くなく、 > + Lispのように原始的またはエレファントでなく、 > + Prologのように変態的なところはなく、 > + Javaのように硬すぎることはなく、 > + Haskellのように抽象的すぎない > > ほどよい言語である <!-- .element: style="font-size:66%" --> 引用元:http://www.slideshare.net/Nikoriks/julia-28059489/8 <!-- .element: style="font-size:71%" --> ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## Julia とは?(3) > + C のように高速だけど、 Ruby のような動的型付言語である > + Lisp のようにプログラムと同等に扱えるマクロがあって、しかも Matlab のような直感的な数式表現もできる > + Python のように総合的なプログラミングができて、 R のように統計処理も得意で、 Perl のように文字列処理もできて、 Matlab のように線形代数もできて、 shell のように複数のプログラムを組み合わせることもできる > + 超初心者にも習得は簡単で、 超上級者の満足にも応えられる > + インタラクティブにも動作して、コンパイルもできる <!-- .element: style="font-size:50%" --> ([Why We Created Julia](http://julialang.org/blog/2012/02/why-we-created-julia) から抜粋・私訳) <!-- .element: style="font-size:71%" --> Note: いろんな言語の「いいとこどり」言語!ってことでっ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## 要するに <!-- .element: style="font-size:300%" --> + 動的言語なのに速い! + 文法も覚えやすい! + 数値計算に強い! <!-- .element: style="font-size:180%" --> Note: 機械学習とかにも持って来いっ! ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## 主な機能 <!-- .element: style="font-size:280%" --> + [多重ディスパッチ](https://docs.julialang.org/en/v1/manual/methods/) + [動的型システム](https://docs.julialang.org/en/v1/manual/types/) + [並行・並列処理](https://docs.julialang.org/en/v1/manual/parallel-computing/)、コルーチン + [組込パッケージマネージャ](https://docs.julialang.org/en/v1/stdlib/Pkg/) <!-- .element: style="font-size:160%" --> Note: っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ## 文法・関数 Note: 以降、ほぼ過去スライドからのコピペ。すっ飛ばして先へ進んで戴いてもOKっ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 基本的な演算 ```julia julia> 1 + 2 - 3 * 4 # 四則演算(除算以外) -9 julia> 7 / 5 # `整数 / 整数` の結果は浮動小数 1.4 julia> 7 ÷ 5 # `整数 ÷ 整数` の結果は整数 1 julia> 2 ^ 10 # 冪乗は `^` 1024 julia> 123 & 234 | 345 # 論理積 / 論理和 376 julia> 123 ⊻ 234 # 排他的論理和(==`xor(123, 234)`) 145 ``` <!-- .element: style="font-size:46%" --> Note: 整数同士の除算は実数になりますっ 整数除算演算子 `÷` が別に存在します(Python の `//` 相当)っ また冪乗も(`**` ではなく)`^` ですっ `⊻` は `\xor`+<kbd>Tab</kbd> または `\veebar`+<kbd>Tab</kbd> で変換できますっ ちなみに先ほどの `÷` も `\div`+<kbd>Tab</kbd>で(基本的に ${\rm \TeX}$ の書式)っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 配列 ```julia julia> a = [1, 2, 3, 4, 5] 5-element Array{Int64,1}: 1 2 3 4 5 julia> a[1] # Julia は 1-origin 1 julia> println(a[2:3]) # 範囲指定は両端含む [2, 3] ``` <!-- .element: style="font-size:50%" --> Note: 1-origin であることに注意すればあとは普通の配列っ あと `a:b` は範囲(`Range`)の記法。両端を含む(Ruby の `a..b` と同じ)っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 配列の内包表記 (1) ```julia julia> a = [n^2 for n=1:5] 5-element Array{Int64,1}: 1 4 9 16 25 julia> A = [x+10y for y=1:3, x=1:3] 3×3 Array{Int64,2}: 11 12 13 21 22 23 31 32 33 ``` <!-- .element: style="font-size:50%" --> Note: 内包表記の記法は Python に類似っ かつ、`for` にカンマ区切りで複数のイテレータを渡すことで2次元以上の配列も作成可能っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 配列の内包表記 (2) ```julia julia> [(a,b,c) for c=1:15,b=1:15,a=1:15 if a^2+a*b+b^2==c^2] 6-element Array{Tuple{Int64,Int64,Int64},1}: (3, 5, 7) (5, 3, 7) (6, 10, 14) (7, 8, 13) (8, 7, 13) (10, 6, 14) ``` Note: Python と同様に `if` で条件を指定することも可能っ あと Python と同様、`[○ for ○=○]` を `(○ for ○=○)` と書くと配列ではなくて `Generator` が返りますっ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### ベクトル ```julia julia> x = [1., 2., 3.]; y = [3., 1., 2.]; julia> x + y # `x .+ y` と書いても同じ(elementwise operation) [4., 3., 5.] julia> x .* y # これは `x * y` と書くとNG [3., 2., 6.] julia> using LinearAlgebra julia> x ⋅ y # 内積(dot積、`dot(x, y)` と書いても同じ) 11.0 julia> x × y # 外積(cross積、`cross(x, y)` と書いても同じ) [1., 7., -5.] ``` <!-- .element: style="font-size:50%" --> Note: Julia では実は1次元配列がベクトルの扱いっ `⋅` は `\cdot`+<kbd>Tab</kbd>、`×` は `\times`+<kbd>Tab</kbd>(これらを利用するには `using LinearAlgebra` 必要)っ あとこれらや先ほどの `÷` や `⊻` などのように、ASCIIの範囲を超えたUnicode文字の演算子(そのほとんどが $\TeX$ 由来)が Julia にはたくさんあります(他には例えば比較演算子の `≤` `≥` や、集合の要素 `∈` や包含関係 `⊆` などなど) ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 行列 ```julia julia> A = [1 2; 3 4] # この記法は MATLAB/Octave 由来 2×2 Array{Int64,2}: 1 2 3 4 julia> A' # `○'` は転置行列の記法(これも MATLAB/Octave 由来) 2×2 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}: 1 3 2 4 julia> transpose(A) # 正確には転置行列はこっち 2×2 LinearAlgebra.Transpose{Int64,Array{Int64,2}}: 1 3 2 4 ``` <!-- .element: style="font-size:50%" --> Note: Julia では2次元配列が行列の扱いっ あと `○.'` という書式は廃止されました(`transpose(A)` 使ってね)っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 行列の演算 ```julia julia> A = [1 2; 3 4]; B = [3 0; 0 6]; julia> A + B # A .+ B でも同様 2×2 Array{Int64,2}: 4 2 3 10 julia> A * B # matrix multiply 2×2 Array{Int64,2}: 3 12 9 24 julia> A .* B # elementwise multiply 2×2 Array{Int64,2}: 3 0 0 24 ``` <!-- .element: style="font-size:48%" --> Note: 行列は `*` で通常の行列積になりますっこれ便利っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### ブロードキャスト ```julia julia> sin(0.1) 0.09983341664682815 julia> sin.([0.1, 0.2, 0.3, 0.4]) 4-element Array{Float64,1}: 0.0998334 0.198669 0.29552 0.389418 julia> [0.1, 0.2, 0.3, 0.4] .^ 2 # => [0.01, 0.04, 0.09, 0.16] ``` <!-- .element: style="font-size:50%" --> Note: 関数名と `(` の間に `.` を置くと、普通の関数を配列に拡張してくれる(ブロードキャスト)っ `.^` のように演算子の前に `.` を書いても同様(先ほど出た `.+` `.*` もブロードキャスト)っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 関数定義 ```julia julia> f(x) = x^2 + 2x - 1 f (generic function with 1 method) julia> f(1) 2 julia> f.(1:5) # => [2, 7, 14, 23, 34] ``` Note: 数学のように直感的な記述で関数を定義可能っ `2x` は `2*x` の省略形、曖昧さがなければリテラルと他の識別子が続く場合などに勝手に乗算と解釈してくれるっ またユーザ定義関数も `.` をつけて自動的にブロードキャスト対応っ ---- <!-- .slide: data-background-color="rgba(213,99,92,0.3)" --> ### 有理数・複素数 ```julia julia> 1//2 == 0.5 true julia> 1//2 - 1//3 1//6 julia> 1im ^ 2 == -1 true julia> (1.0 + 0.5im) * (2.0 - 3.0im) 3.5 - 2.0im ``` Note: 有理数・複素数を標準サポート。 `//` は有理数除算(結果は有理数) `im` は虚数単位。 どちらも四則演算も普通に書けますっ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> # Holy Traits Pattern Note: Holy Traits Patternっ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ## Holy Traits ? + 別名 "Tim Holy Traits Trick" + 多言語にもある `trait` のような仕組みを、機能拡張することなく Julia に取り入れたもの。 ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ## そもそも `trait` って? + (オブジェクトの)振る舞いを定義したもの + 継承(サブタイピング)によらない機能追加を可能とするもの + 多言語の Mix-in のようなこともできる ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ## 詳しくは… ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> [![Holy Traits Pattern (book excerpt)](https://i.imgur.com/eO0ReiF.png) https://ahsmart.com/pub/holy-traits-design-patterns-and-best-practice-book.html](https://ahsmart.com/pub/holy-traits-design-patterns-and-best-practice-book.html) <!-- .element: style="font-size:60%" --> Note: 1月に出た本の、著者がHolyTraits部分だけ抜粋して載せたブログ記事。分かりやすい。 --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ## お題:消費税 Note: みんな大好き *消費税* っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia= abstract type 商品 end 本体価格(v::商品) = v.price # 税込価格(v::商品) = … # 本体価格(v::商品) * 1.1 # ??? ``` Note: 商品に対して、本体価格と税込価格を知りたいとします…でもっ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> コート = 衣料品("ダウンコート", 30000) julia> 税込価格(コート) # => 33000 # == 30000 * 1.1 julia> にんじん = 飲食料品("にんじん", 100) julia> 税込価格(にんじん) # => 108 # == 100 * 1.08 ``` Note: 飲食料品など一部の商品は軽減税率対象なので場合分けしたいっ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ### 税率 trait Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=4 abstract type 税率 end struct 標準税率 <: 税率 end struct 軽減税率 <: 税率 end ``` Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=9 税込価格(v::T) where {T <: 商品} = 税込価格(税率(T), v) 税込価格(::標準税率, v) = floor(Int, 本体価格(v) * 1.1) 税込価格(::軽減税率, v) = floor(Int, 本体価格(v) * 1.08) ``` Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ### 標準税率 Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=13 税率(::Type{<:商品}) = 標準税率() ``` Note: 基本的には標準税率が適用されるはずなので、デフォルトをそのように定義っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> #### 例 Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> struct 衣料品 <: 商品 name::String price::Int end julia> コート = 衣料品("ダウンコート", 30000); julia> 税込価格(コート) # => 33000 ``` Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ### 軽減税率 Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> #### 例:新聞(定期購読) Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=15 struct 定期購読新聞 <: 商品 name::String term::AbstractRange{Date} price::Int end 定期購読新聞(name, date::Date, price) = 定期購読新聞(name, date:Day(1):lastdayofmonth(date), price) 定期購読新聞(name, startdate::Date, enddate::Date, price) = 定期購読新聞(name, startdate:Day(1):enddate, price) 税率(::Type{定期購読新聞}) = 軽減税率() ``` Note: 新聞(定期購読契約)は軽減税率対象っ 売店とかコンビニで買う新聞(単品)は標準税率っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> 新聞_年間契約 = 定期購読新聞( "毎朝新聞", Date(2020, 2, 1), Date(2021, 1, 31), 50000); julia> 税込価格(新聞_年間契約) # => 54000 ``` Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> #### 例:飲食料品 Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=27 struct 飲食料品 <: 商品 name::String price::Int end # 税率(::Type{飲食料品}) = 軽減税率() # ??? ``` Note: 飲食料品は軽減税率対象…?っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> **持ち帰りか店内飲食かで変わる!** <!-- .element: style="font-size:240%" --> Note: 飲食料品は店内飲食かどうかで軽減税率対象かどうかが決まるっ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=32 abstract type 提供形態 end struct 持ち帰り <: 提供形態 end struct 店内飲食 <: 提供形態 end 税率(::Type{飲食料品}, ::Type{<:提供形態}) = 標準税率() 税率(::Type{飲食料品}, ::Type{持ち帰り}) = 軽減税率() 税込価格(v::飲食料品, ::K = 持ち帰り()) where {K <: 提供形態} = 税込価格(税率(飲食料品, K), v) ``` Note: ということで 提供形態 trait (?) も導入っ この場合は 提供形態 strategy の方が正しいかも ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=42 # aliases 外食() = 店内飲食() イートイン() = 店内飲食() 出前() = 持ち帰り() 宅配() = 持ち帰り() ``` Note: 外食(レストラン等)は店内飲食のことっ イートインは、椅子や机などの店内飲食設備が整っていてそこを利用する場合っ 出前・宅配は持ち帰り扱いっ(めんどくさいっ) ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> あんぱん = 飲食料品("あんぱん", 128); julia> 税込価格(あんぱん, 持ち帰り()) # => 138 julia> 税込価格(あんぱん, イートイン()) # => 140 ``` Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> そば = 飲食料品("かけそば", 580); julia> 税込価格(そば, 店内飲食()) # => 638 julia> 税込価格(そば, 出前()) # => 626 ``` Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> #### 一体型商品 Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> > 飲食料品とその他(おまけ、容器等)の一体型商品の場合: > > + 飲食料品以外が価格比で本体価格の 1/3 を超える > → 軽減税率対象外(=標準税率) > + 例:ティーカップとお菓子のセット、おまけがメインの食玩・駄菓子 > + 本体価格が ¥10,000 以上 > → 軽減税率対象外(=標準税率) > + 例:高級おせち料理セット > + 上記2つをいずれも満たさないもの > → 軽減税率 > + 例:おまけシール付きのお菓子(おまけのほうが十分に安いもの) <!-- .element: style="text-align: left; font-size: 0.6em" --> Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=49 abstract type PriceCost end struct Expensive <: PriceCost end struct Inexpensive <: PriceCost end PriceCost(v::Int) = v ≥ 10000 ? Expensive() : Inexpensive() ``` Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=55 abstract type PriceRateOfFood end struct HighRate <: PriceRateOfFood end struct LowRate <: PriceRateOfFood end PriceRateOfFood(price, groceriesprice) = (price - groceriesprice) * 3 > price ? LowRate() : HighRate() ``` Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia=62 struct 一体型商品{PC<:PriceCost, PR<:PriceRateOfFood} <: 商品 name::String price::Int function 一体型商品(name, price, groceriesprice) pc = PriceCost(price) pr = PriceRateOfFood(price, groceriesprice) new{typeof(pc), typeof(pr)}(name, price) end end 税率(::Type{<:一体型商品}) = 標準税率() 税率(::Type{一体型商品{Inexpensive, HighRate}}) = 軽減税率() ``` Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ```julia julia> おせちセット = 一体型商品("高級おせち料理セット", 12000, 8000); julia> 税込価格(おせちセット) # => 13200 # 標準税率 julia> チョコたまご = 一体型商品("チョコたまご", 400, 200); julia> 税込価格(チョコたまご) # => 440 # 標準税率 julia> シールチョコ = 一体型商品("おまけシール付きチョコ", 120, 100); julia> 税込価格(シールチョコ) # => 129 # 軽減税率 ``` Note: っ --- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ## まとめ Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> + 継承関係(サブタイピング)と関係なく機能定義できる! + 実装を共有できる(型ごとに実装を書く必要がない)! <!-- .element: style="font-size: 160%" --> Note: っ ---- <!-- .slide: data-background-color="rgba(96,173,81,0.3)" --> ### 発展・応用 + 2値ではなく3値以上のふるまいの違いにも容易に対応可能 + 標準税率・軽減税率以外に割増税率が増えても追記するだけ + 自分で定義した型にも容易に適用可能 + 商品型以外の型でもOK <!-- .element: style="font-size: 120%" --> Note: っ --- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> # 結論 ---- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> + Holy Traits を使いこなせ! + 多重ディスパッチ使いこなせ! + Julia 楽しい! Note: っ --- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> # リンク ---- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> ## 実験Note + [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/antimon2/JuliaTokai202002_HolyTraitsSample/master?filepath=%E6%B6%88%E8%B2%BB%E7%A8%8E.jl.ipynb) Note: さっそく binder 試してみましたっ (なぜか Jupyter Notebook の Gist it がうまく動作しなかった…) ---- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> ## 参考リンク + [Hands-On Design Patterns with Julia 1.0](https://www.packtpub.com/application-development/hands-design-patterns-julia-10)(書籍、英語) + [Holy Traits Pattern (book excerpt)](https://ahsmart.com/pub/holy-traits-design-patterns-and-best-practice-book.html)(↑の著者による Holy Traits Pattern 部の抜粋) + [Trait-based dispatch - Methods - The Julia Language](https://docs.julialang.org/en/v1/manual/methods/#Trait-based-dispatch-1) + [[Julia] Holy trait 〜 共通の関数定義を気軽に記述しよう - Qiita](https://qiita.com/tenfu2tea/items/09c3528b2144d1eac74a) by [@tenfu2tea](https://qiita.com/tenfu2tea) --- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> # おまけ ---- <!-- .slide: data-background-color="rgba(204,102,51,0.3)" --> ## Python東海 ---- <!-- .slide: data-background-color="rgba(204,102,51,0.3)" --> [![Python東海 第41回勉強会](https://i.imgur.com/3V0MIbW.png) https://connpass.com/event/165645/](https://connpass.com/event/165645/) Note: 来月開催!(再) --- <!-- .slide: data-background-color="rgba(170,121,193,0.3)" --> ご清聴ありがとうございます。 Note: ご清聴ありがとうございますっ!
{"metaMigratedAt":"2023-06-15T04:01:47.941Z","metaMigratedFrom":"YAML","title":"Holy Traits 入門","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"theme\":\"league\"}","contributors":"[{\"id\":\"80062a4b-8dad-49ac-95bf-848ce0686e9e\",\"add\":10029,\"del\":13528}]"}
    1620 views