Successfully reported this slideshow.
Your SlideShare is downloading. ×

静的型付け言語 Crystal

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
変数と型
変数と型
Loading in …3
×

Check these out next

1 of 41 Ad
Advertisement

More Related Content

Advertisement

Recently uploaded (20)

静的型付け言語 Crystal

  1. 1. 静的型付け言語 Crystal Crystal The Programming Language with Static Typing Hirofumi Wakasugi (@5t111111)
  2. 2. Crystalは静的型付けの プログラミング言語です。
  3. 3. 静的型付け • 変数などの型はコンパイル時に決定されている • 型チェックによって事前にバグを捕捉しやすい • 変数などの型は実際の実行時の値になる • 柔軟で再利用性の高いプログラムを書きやすい 動的型付け
  4. 4. 動的型付けのRubyと 静的型付けのCrystal どっちが優れてるかとか そういう話はしません!
  5. 5. Crystalが 静的型付け言語として どのように働くか 淡々と見ていきます。
  6. 6. 変数の定義 a = 3 b = "we are like crystal, we break easy" c = [1, 2, 3] • 変数 a の型は Int32 • 変数 b の型は String • 変数 c の型は Array(Int32) 変数は初めて値が代入されたときに宣言される
  7. 7. 変数の定義 • 変数 a の型は Int32 • 変数 b の型は String • 変数 c の型は Array(Int32) 変数は初めて値が代入されたときに宣言される a = 3 b = "we are like crystal, we break easy" c = [1, 2, 3] 型推論
 Type Inference

  8. 8. 変数への再代入 これはどうなる? エラーになってしまうの? すでに宣言されて型が決まっている変数に代入する a = "we are like crystal, it is not easy" a = 100
  9. 9. 変数への再代入 別の型を変数に代入してもエラーにはならない 変数の型は代入される式 (値) によって型推論される すでに宣言されて型が決まっている変数に代入する a = "we are like crystal, it is not easy" # ここで変数 a は String a = 100 # ここで変数 a は Int32
  10. 10. Arrayの型 これはどうなる? いけそうじゃない? Int32のArrayにString型の要素を追加する a = [1, 2, 3] a << "we are like crystal"
  11. 11. Arrayの型 Int32のArrayにString型の要素を追加する a = [1, 2, 3] a << "we are like crystal" no overload matches 'Array(Int32)#<<' with types String Overloads are: - Array(Int32)#<<(value : Int32) a << "we are like crystal" ^~ これは コンパイルエラー Error
  12. 12. 空のArray 型を指定せずに空のArrayを宣言することはできない a = [] # Syntax Error a = [] of Int32 # OK! ということは、 異なる型の要素を含むArrayは 作れない?
  13. 13. Union型 ArrayはGeneric型であり、(Union型を含む) 要素 の型を指定できる
 Hashなど、他のコンテナ (コレクション) 型も同様 型の組み合わせを表現するUnion型 a = [1, 2, 3, "we are like crystal"] #=> Array(String | Int32) a = [] of String | Int32 #=> Array(String | Int32)
  14. 14. Generic型 (後で説明しますしません)
  15. 15. メソッド呼び出し これはどうなる? エラーになってしまうの? ある型 (クラス) に存在しないメソッドを呼び出した場合 a = 3 a.size
  16. 16. メソッド呼び出し ある型 (クラス) に存在しないメソッドを呼び出した場合 a = 3 a.size undefined method 'size' for Int32 a.size ^~~~ これは コンパイルエラー Error
  17. 17. メソッド引数 def put_size(x) puts x.size end put_size("crystal") put_size(5) undefined method 'size' for Int32 puts x.size ^~~~ Error 引数で渡されたオブジェクトにメソッドがない
  18. 18. 型制約 def put_size(x : String) puts x.size end put_size(5) no overload matches 'put_size' with types Int32 Overloads are: - put_size(x : String) put_size(5) ^~~~~~~~ Error 引数に型アノテーションを指定し型を制約する
  19. 19. 型制約があると安心だね!
 引数はどんどん型制約しよう!
  20. 20. Re: メソッド引数 def put_size(x) puts x.size end put_size("crystal") put_size([1, 2, 3]) 引数で渡されたオブジェクトにメソッドがある えっ?
  21. 21. Re: メソッド引数 def put_size(x) puts x.size end put_size("crystal") put_size([1, 2, 3]) 引数で渡されたオブジェクトにメソッドがある 7 3 Result エラーなく正常終了する
  22. 22. Re: def put_size(x) puts x.size end put_size("crystal") put_size([1, 2, 3]) 引数で渡されたオブジェクトにメソッドが 7 3 Result エラーなく正常終了する 明確に型制約がされてい なければ、ある型が呼び 出されるメソッドに応答 するとき、コンパイラの 型チェックは通る。
  23. 23. ダックタイピング的な型システム 型そのものやその継承関係に依存しない、 柔軟性を持った静的型付けになっている シグネイチャが特に重要であるという点で、
 Structural Subtyping (構造的部分型付け) と言ってもよいかも
  24. 24. Re: Re: メソッド引数 def put_size(x) puts x.size end put_size("crystal") put_size(5) undefined method 'size' for Int32 puts x.size ^~~~ Error 型制約をしなくてもコンパイル時にエラーが捕捉される 不必要な型制約は 柔軟性を欠く
  25. 25. インスタンス変数 インスタンス変数も代入される値から型推論される class Person getter name def initialize(@name) end end barney = Person.new "Barney" barney.name #=> "Barney" barney.name.size #=> 6
  26. 26. barney = Person.new "Barney" barney.name.size one = Person.new 1 Re: インスタンス変数 インスタンス変数に異なる型を与えて初期化 なんかおかしいとこある?
  27. 27. barney = Person.new "Barney" barney.name.size one = Person.new 1 Re: インスタンス変数 インスタンス変数に異なる型を与えて初期化 undefined method 'size' for Int32 (compile-time type is (String | Int32)) barney.name.size #=> 4 ^~~~ これは コンパイルエラー Error
  28. 28. if var.is_a?(…) is_a? で型をチェックし制限する if a.is_a?(String) # ここでは a が # String で「ある」ことが保証される else # ここでは a が # String では「ない」ことが保証される end コンパイル時リフレクションによる型の保証
  29. 29. if var.responds_to?(…) responds_to? で応答をチェックし制限する if a.responds_to?(:size) # ここでは a が # size に応答「する」ことが保証される else # ここでは a が # size に応答「しない」ことが保証される end コンパイル時リフレクションによるメソッド応答の保証
  30. 30. Re: Re: インスタンス変数 is_a? や responds_to? で制限する if (name = barney.name).is_a?(String) name.size #=> 4 end if (name = barney.name).responds_to?(:size) name.size #=> 4 end インスタンス変数の場合は、上記のように一度変数に代入する必要がある
  31. 31. as as で型を制限することもできる name = barney.name as String name.size #=> 4 • asは実行時にチェックを行う • 対象がStringでなかった場合には例外が発生 • asはキャストではない (別の型への変換はしない)
  32. 32. nil-able ある型がNil型を持つ可能性 a = [] of String? a.class #=> Array(String?) a << "crystal" #=> ["crystal"] a << nil #=> ["crystal", nil] • String?は型がNil型を持つことを意味する • (String ¦ Nil) というUnion型と同様
  33. 33. nil-able インスタンス変数 initializeで初期化されないインスタンス変数 class Person getter name property address def initialize(@name) end end barney = Person.new "Barney" barney.address = "Manchester" barney.address.size
  34. 34. nil-able インスタンス変数 initializeで初期化されないインスタンス変数 barney = Person.new "Barney" barney.address = "Manchester" barney.address.size undefined method 'size' for Nil (compile-time type is String?) barney.address.size ^~~~ Error これは コンパイルエラー initializeで初期化されないインスタンス変数はNil型を持つ
  35. 35. Re: nil-able インスタンス変数 インスタンス変数をinitializeの外側で初期化する class Person getter name property address @address = "nowhere" def initialize(@name) end end barney = Person.new "Barney" barney.address = "Manchester" barney.address.size #=> 10
  36. 36. インスタンス変数の型指定 インスタンス変数を型アノテーションで指定する class Person … @address :: String … end • @addressにString以外の型を代入するとエラー • 型のデフォルト値は存在しないので初期化は必要
  37. 37. まとめ • Crystal Ruby • 中でも静的型付けによる違いは非常に大きい それでも、 We love Ruby's efficiency for writing code. というのがCrystalの出発点の1つであるように、 Rubyの柔軟性や生産性、気持ちいい書き味を維持して 静的型付けにしようとする工夫が随所に見られる。
  38. 38. 話せなかった話題たち • Generic型 (Generics) • 例外処理内での型推論の働き • クロージャ内での変数の型 • マクロにおける型情報へのアクセス • typeof、Object#tryなどのメソッド • etc. etc.
  39. 39. http://ja.crystal-lang.org/docs/ 今日話せなかった内容もドキュメントに記載があります
  40. 40. ドキュメントをいつもup-to-dateにするために 翻訳を手伝ってくれる方を募集しています GitHub https://github.com/crystal-jp/ja.crystal-lang.org Gitter https://gitter.im/crystal-jp/ja.crystal-lang.org もしくは @5t111111 まで直接お知らせください! Slack http://crystal.pine.moe/
  41. 41. 本スライド中のサンプルコード およびその出力内容は すべて Crystal 0.9.0 で確認しています ご静聴ありがとうございました。

×