$30 off During Our Annual Pro Sale. View Details »

Juliaってどんなことができるの? for JuliaTokai #16

Juliaってどんなことができるの? for JuliaTokai #16

JuliaTokai #16 LT資料

GOTOH Shunsuke

October 01, 2023
Tweet

More Decks by GOTOH Shunsuke

Other Decks in Technology

Transcript

  1. Julia って
    どんなことができるの?
    2023/10/01 JuliaTokai #16
    antimon2(後藤 俊介)

    View Slide

  2. お品書き
    ● お前誰よ?
    ● Julia本 発刊から半年が経ちました
    ● 簡単な Julia の紹介
    ● Julia でできること?

    View Slide

  3. お前誰よ?

    View Slide

  4. 自己紹介
    ● 名前:後藤 俊介
    ● 所属:有限会社 来栖川電算
    ● コミュニティ:🌟機械学習名古屋, 🌟JuliaTokai,
    ⭐Python東海, ⭐Ruby東海, ⭐jl.dev, …
    ● 言語:Julia, Python, Ruby, …
    ● SNS等:                  (@antimon2)
    ● SNS等(2):      (@antimon2.jl)
    ● 著書:実践Julia入門

    View Slide

  5. https://www.kurusugawa.jp

    View Slide

  6. https://twitter.com/antimon2/status/1635765451220459520

    View Slide

  7. Julia本 発刊から半年が経ちました

    View Slide

  8. https://www.amazon.co.jp/o/ASIN/4297133504

    View Slide

  9. https://www.amazon.co.jp/product-reviews/4297133504/ref=c
    m_cr_dp_d_show_all_btm?ie=UTF8&reviewerType=all_reviews

    View Slide

  10. 半年で変わったこと、イベント

    View Slide

  11. 研究集会に呼ばれた
    ● 2023/07/10-12
    ● Juliaチュートリアル講演
    2コマ担当
    ● アーカイブ(動画):
    ○ 型と多重ディスパッチ
    ○ スレッド並列の基礎
    https://joint.imi.kyushu-u.ac.jp/post-9030/

    View Slide

  12. Juliaの仕事(10月~)
    ● 会社に案件打診
    ● 10月から開始
    ● ※詳細割愛

    View Slide

  13. 印税
    ● 2023/06 最初の振込
    ○ 最低保証部数分
    ○ +電子版の売上分
    ● ※詳細割愛

    View Slide

  14. 簡単な
    Juliaの紹介

    View Slide

  15. View Slide

  16. Julia とは?(1)
    ● The Julia Language
    ● 最新 v1.9.3(2023/08/24)
    ○ LTS:v1.6.7(2022/07/19)
    ○ 次期:v1.10.0-β2(2023/08/17)
    ● 科学技術計算に強い!
    ● 動作が速い!(LLVM JIT コンパイル)

    View Slide

  17. Julia とは?(2)
    ● Rのように中身がぐちゃぐちゃでなく、
    ● Rubyのように遅くなく、
    ● Lispのように原始的またはエレファントでなく、
    ● Prologのように変態的なところはなく、
    ● Javaのように硬すぎることはなく、
    ● Haskellのように抽象的すぎない
    ほどよい言語である
    引用元:http://www.slideshare.net/Nikoriks/julia-28059489/8

    View Slide

  18. Julia とは?(3)
    ● C のように高速だけど、
    Ruby のようなダイナミズムを併せ持っている
    ● Lisp のような真のマクロを持ちながら、
    MATLAB のような直感的な数式表現もできる
    ● Python のように総合的なプログラミングができて、
    R のように統計処理も得意で、
    Perl のように文字列処理もできて、
    MATLAB のように線形代数もできて、
    shell のように複数のプログラムを組み合わせることもできる
    ● 超初心者にも習得は容易でありながら、
    ハッカーの満足にも応えられる
    ● インタラクティブな動作環境もあって、コンパイルもできる
    (Why We Created Julia から抜粋・私訳)

    View Slide

  19. 要するに
    ● 動的言語なのに速い!
    ● 文法も覚えやすい!
    ● 数値計算に強い!

    View Slide

  20. Julia の主な特徴
    ● 多重ディスパッチ
    ● 動的型システム
    ● 並行・並列処理、コルーチン
    ● 組込パッケージマネージャ

    View Slide

  21. Julia でできること?

    View Slide

  22. なんでもできる!
    大抵のプログラミング言語でできることなら。(当たり前)
    その気になれば(だから当たり前)

    View Slide

  23. Juliaでできること(よくある答え)
    ● 数値計算
    ○ 数値線形代数、非線形方程式の求解、数値積分、常微分方程式、最適化問題、etc…
    ● データ解析
    ○ 統計、検定、データ操作、データプロット、時系列解析、etc…
    ● 機械学習
    ○ パターン認識、分析・予測、最適化、生成(LLM)、etc…

    ● これらは実践Julia入門でも簡単に紹介しているしググればいくらでも情報出て
    くる(ようになってきた(ので今さら(なので割愛

    View Slide

  24. 観点を絞って…

    View Slide

  25. Julia は
    大規模プログラミングに
    耐えうるか?

    View Slide

  26. 例:SOLID原則

    View Slide

  27. SOLID原則(1)
    ● (主にオブジェクト指向開発における)柔軟で保守性の
    高い設計のための5原則。
    ● 参照: https://ja.wikipedia.org/wiki/SOLID

    View Slide

  28. SOLID原則(2)
    ● S: 単一責任の原則 (Single-Responsibility Principle)
    ● O: オープン・クローズドの原則(Open/Closed Principle)
    ● L: リスコフの置換原則(Liskov Substitution Principle)
    ● I: インターフェース分離の原則 (Interface Segregation Principle)
    ● D: 依存性逆転の原則(Dependency Inversion Principle)

    View Slide

  29. SOLID原則(2)
    ● S: 単一責任の原則 (Single-Responsibility Principle)
    ● O: オープン・クローズドの原則(Open/Closed Principle)
    ● L: リスコフの置換原則(Liskov Substitution Principle)
    ● I: インターフェース分離の原則 (Interface Segregation Principle)
    ● D: 依存性逆転の原則(Dependency Inversion Principle)

    View Slide

  30. オープン・クローズドの原則(Open/Closed Principle)
    ● software entities (classes, modules, functions, etc.) should
    be open for extension, but closed for modification.
    ● (参考訳:ソフトウェアの実体(クラス、モジュール、関数など)は、拡張に対して開
    かれているべきであり、修正に対して閉じていなければならない)

    ● 意訳:機能拡張が必要な場合に、既存のコードには修正を加えず
    に新しくコードを追加するだけで対応できるべきである

    View Slide

  31. オープン・クローズドの原則(for Julia)(1)
    型システムと多重ディスパッチがすべて解決!
    ● 新しい型に既存の振る舞い(関数)を適用させたい場合、その関数に新しい型を
    受け取るメソッドを追加(多重定義)して振る舞いを定義するだけでOK。
    ● 既存の型に新しい振る舞い(関数)を適用させたい場合、その関数に既存の型を
    受け取るメソッドを追加(多重定義)して振る舞いを定義するだけでOK。
    ● いずれにせよ「新しいコードを追加」することで機能の拡張が可能。
    (=既存のコードの修正不要(な状況に簡単にできる))

    View Slide

  32. オープン・クローズドの原則(for Julia)(2)
    具体例:
    ● Base.show() 関数
    (文字列化時や REPL
    での表示など)
    ● を、ユーザ定義型に適
    用する例→
    julia> @kwdef struct 犬
    鳴き声::String = "わん"
    end

    julia> dog1 = 犬(鳴き声="にゃー")
    犬("にゃー") # `Base.show()` を多重定義していない場合のデフォルト表示
    julia> # `Base.show()` を多重定義して機能拡張
    Base.show(io::IO, dog::犬) =
    print(io, "これは", '"', dog.鳴き声, '"', "と鳴く犬です。")
    julia> dog1
    これは"にゃー"と鳴く犬です。 # `Base.show()` を多重定義している場合の表示

    View Slide

  33. オープン・クローズドの原則(for Julia)(3)
    具体例:
    ● 鳴く() 関数を定義
    ● Julia 標準の型にも
    適用する例→
    julia> 鳴く(dog::犬) = dog.鳴き声
    鳴く (generic function with 1 method)
    julia> 鳴く(dog1)
    "にゃー"
    julia> 鳴く(::AbstractVector) = "きゅー"
    鳴く (generic function with 2 methods)
    julia> 鳴く(1:10)
    "きゅー"
    julia> 鳴く([1 2; 3 4]) # 行列は鳴かない(定義されていなければエラーになる)
    ERROR: MethodError: no method matching 鳴く(::Matrix{Int64})
    # : 《以下略》

    View Slide

  34. インターフェース分離の原則 (Interface Segregation Principle)
    ● Many client-specific interfaces are better than one
    general-purpose interface.
    ● (参考訳:汎用なインターフェースが一つあるよりも、各クライアントに特化したイ
    ンターフェースがたくさんあった方がよい)

    ● 意訳:不要なメソッドが存在する状況を作るな!

    View Slide

  35. インターフェース分離の原則 (for Julia)(1)
    そもそも…
    ● Julia には 継承はない!
    ● Julia には インターフェースもない!
    ○ 言語仕様としてのMix-inやトレイトもないが、型システムと多重ディ
    スパッチを利用した Holyトレイト というトリックは存在
    ● Julia の関数は 総称関数(Generic Function) と言い、これ
    がそもそも抽象メソッドやインターフェースの役割
    ○ 振る舞い(関数)は(特定の)型に依存しない!(重要)
    ○ シグニチャにより呼び出される各実体を メソッド と呼ぶ

    View Slide

  36. インターフェース分離の原則 (for Julia)(2)
    結局 Julia の場合…
    ● まず「関数」を宣言し、役割を与える。
    ● 必要な「型」(の組合せ(=シグニチャ))にだけその関数を
    適用できるように、関数を定義(多重定義)する。
    (基本はこれでOK!)
    ● いくつかの型に共通の振る舞い(共通実装)を与えたいな
    ら、Holyトレイト の仕組みを活用する。

    View Slide

  37. インターフェース分離の原則 (for Julia)(3)
    具体例:
    ● 桜 型と 花の色() 関
    数を定義
    ● Julia 標準の型にも
    適用する例
    ● かつ、不要な型には適
    用しない例
    julia> @kwdef struct 桜
    色::String = "桜色"
    end

    julia> 花の色(blossom::桜) = blossom.色
    花の色 (generic function with 1 method)
    julia> 淡墨桜 = 桜(色="薄墨色");
    julia> 花の色(淡墨桜)
    "薄墨色"
    julia> 鳴く(淡墨桜) # 桜は鳴かない(定義されていなければエラーになる)
    ERROR: MethodError: no method matching 鳴く(::桜)
    # : 《略》
    julia> 花の色(犬()) # 犬は花が咲かない(同様のエラー)
    ERROR: MethodError: no method matching 花の色(::犬)
    # : 《略》

    View Slide

  38. インターフェース分離の原則 (for Julia)(4)
    Holyトレイトとは…
    実践Julia入門 p.331- を参照(見てね)

    View Slide

  39. SOLID原則(3)
    他の原則について…
    ● 単一責任の原則(S): 型の定義分け。設計だけの問題。
    ● リスコフの置換原則(L): ある意味当たり前、ある意味「継承のな
    い Julia には当てはまらない」
    ● 依存性逆転の原則(D): 関数による抽象化と、それを利用した依
    存性注入(DI)が可能なので普通にできる(要設計スキル)

    View Slide

  40. 例:デザインパターン

    View Slide

  41. デザインパターン(1)
    ● プログラムの設計ノウハウを再利用しやすいようにカタ
    ログ化したもの
    ● GoFの(オブジェクト指向における)23のデザインパ
    ターンが有名
    ● マルチスレッドのデザインパターンも存在
    ● 参照: https://ja.wikipedia.org/wiki/デザインパ
    ターン_(ソフトウェア)

    View Slide

  42. デザインパターン(2)
    Julia 標準に組み込み or よく利用されるデザインパターン…
    ● Factory Method パターン
    ● Singleton パターン
    ● Iterator パターン
    ● Strategy パターン
    ● Producer-Consumer パターン

    View Slide

  43. Factory Method パターン (for Julia)
    ● 抽象型に外部コンスト
    ラクタ(のような関数)
    を定義して、引数に応
    じて派生型のインスタ
    ンスを生成
    ● Holyトレイトのトレイ
    ト型を生成する目的
    で多用されている
    julia> subtypes(Base.IteratorSize)
    4-element Vector{Any}:
    Base.HasLength
    Base.HasShape
    Base.IsInfinite
    Base.SizeUnknown
    julia> Base.IteratorSize(typeof([1 2;3 4])) # Matrix{Int64}
    Base.HasShape{2}()
    julia> Base.IteratorSize(Base.EachLine)
    Base.SizeUnknown()

    View Slide

  44. Singleton パターン (for Julia)
    ● フィールドのない
    struct は
    Singleton Type と
    なりインスタンスは1
    つしか生成されない
    ● Julia 標準では、π(を
    初めとする定数)、
    nothing、missing
    などがシングルトン
    ● 拙著「4-6-4. シング
    ルトン型」等参照
    julia> struct SampleSingleton end
    julia> sngltn1 = SampleSingleton()
    SampleSingleton()
    julia> sngltn2 = SampleSingleton()
    SampleSingleton()
    julia> sngltn1 === sngltn2 # オブジェクトレベルで同一
    true

    View Slide

  45. Iterator パターン (for Julia)
    ● コレクションの要素を
    列挙する仕組み
    ● Julia ではイテレータ
    オブジェクトを作るの
    ではなく、「次の値と
    『状態オブジェクト』を
    返す関数」への定義追
    加(多重定義)という
    かたちで実装される
    ● 拙著「第6章 イテレー
    ション」等参照
    julia> iterate([31, 41, 59, 26, 53])
    (31, 2)
    julia> iterate([31, 41, 59, 26, 53], 2)
    (41, 3)
    julia> iterate([31, 41, 59, 26, 53], 5)
    (53, 6)
    julia> iterate([31, 41, 59, 26, 53], 6) === nothing
    true
    # ↑列挙終了は「戻り値が `nothing` かどうか」で判定

    View Slide

  46. Strategy パターン (for Julia)
    ● 多重ディスパッチ(ポ
    リモーフィズム)を利
    用して、引数の違いで
    異なるアルゴリズムを
    選択出来る
    ● sort() の alg=~
    キーワード引数指定
    で内部でstrategyパ
    ターンを適用
    julia> nums = [31, 41, 59, 26, 53, 58, 97, 93];
    julia> sort(nums) # デフォルトソートアルゴリズム利用
    #> [26, 31, 41, 53, 58, 59, 93, 97]
    julia> sort(nums; alg=QuickSort) # クイックソート
    #> [26, 31, 41, 53, 58, 59, 93, 97]
    julia> sort(nums; alg=MergeSort) # マージソート
    #> [26, 31, 41, 53, 58, 59, 93, 97]

    View Slide

  47. Producer-Consumer パターン (for Julia)
    ● データの 生成 と 消
    費 を非同期で行う
    (並行・並列処理のパ
    ターン)
    ● Julia では Channel
    で実現される
    ● 拙著「9-1. タスクと
    チャネル」等参照
    julia> function collatz_channel(n)
    Channel{Int}() do chnl
    put!(chnl, n)
    while n != 1
    n = iseven(n) ? n ÷ 2 : 3n + 1
    put!(chnl, n)
    end
    end
    end
    collatz_channel (generic function with 1 method)
    julia> collect(collatz_channel(27))
    112-element Vector{Int64}:
    27
    82

    2
    1

    View Slide

  48. デザインパターン(3)
    Julia で簡単に応用可能なパターン…
    ● Template Method パターン(?)

    View Slide

  49. Template Method パターン (for Julia)
    ● (先述の通り)Julia
    の関数はそもそも抽
    象メソッドのような
    ものなので、それを
    そのまま利用すれば
    OK
    ● 例:実践Julia入門
    第5章 多重ディス
    パッチ「5-2-3. 実
    例」など参照
    abstract type AbstractTime end
    function gethour end # ←コレ
    function getminute end # ←コレ
    function getsecond end # ←コレ
    function Base.show(io::IO, time::AbstractTime)
    print(io,
    string(gethour(time), pad=2), # ←ココ
    ':',
    string(getminute(time), pad=2), # ←ココ
    ':',
    string(getsecond(time), pad=2)) # ←ココ
    end
    struct MyTime <: AbstractTime
    hour::Int
    minute::Int
    second::Int
    end
    gethour(time::MyTime) = time.hour
    getminute(time::MyTime) = time.minute
    getsecond(time::MyTime) = time.second
    struct MyTime2 <: AbstractTime
    seconds::Int
    end
    gethour(time::MyTime2) = time.seconds ÷ 3600
    getminute(time::MyTime2) = time.seconds ÷ 60 % 60
    getsecond(time::MyTime2) = time.seconds % 60

    View Slide

  50. 他の原則、
    デザインパターン等
    ● この本が詳しい
    (電子/ペーパー
    バック、Kindle
    版あり)
    https://www.packtpub.com/product/hands-on-design-p
    atterns-and-best-practices-with-julia/9781838648817

    View Slide

  51. 結論

    View Slide

  52. 結論
    ● Julia でも普通に大規模開発(複数人で共同開発と
    か)できるよ
    ● 原則とか設計(デザインパターン)とかは少し学習が
    必要かも
    ● Julia 怖くないよ!
    ● Julia 楽しいよ!

    View Slide

  53. 参考

    View Slide

  54. 参考文献・リンク等
    ● 実践Julia入門(拙著)
    ● Hands-On Design Patterns and Best Practices with
    Julia(さっき紹介したヤツ、洋書)
    ● 研鑽Rubyプログラミング(後半のネタを思いついたきっかけの
    本、訳書、原著:Polished Ruby Programming)
    ● julialang.org(Julia 本家サイト)

    View Slide

  55. ご清聴ありがとうございます。

    View Slide