Better C#の脱却を目指して        bleis-tift    November 24 2012
自己紹介id:bleis-tift / @bleisなごや (こわくない)Microsoft MVP for Visual F#仕事は F#もやるけど、C#も
対象関数型言語初心者を抜け出しつつある人
それなりによく見る光景今まで手続型の言語を使っていたチームで・       ・・C#の代わりに F#を使おう!(もしくは、Java の代わりに Scala を使おう!)→ C#や Java のコードを単に置き換えただけ
Better ○○便利になる部分はある。が、便利な○○どまり、と言うことも多いように思う。 「便利な○○」を抜け出すためには壁があると、思う
壁の例  再帰関数の壁  高階関数の壁  カリー化、コンビネータ、関数合成の壁  型を定義する壁  各言語ごとのよりディープな壁パラダイムの壁を越えるのは大変・               ・・
型を定義する壁C#や Java をはじめとする手続型言語では、型の定義が面倒  型をあまり定義しない習慣  プリミティブな型で済ませてしまうこの悪習を、F#などにも持ち込んでしまう結果、if-elif-else の嵐になるなど
C#での型定義User クラスpublic class User{  public readonly string Name;  public readonly int Age;  public User(string name, int ag...
F#での型定義User レコードtype User = {  Name: string  Age: int}簡単!
比べてみる  C#では、ごてごてした修飾子が必要  C#では、コンストラクタでフィールドの初  期化が必要  C#では、Equals や ToString 等のオーバーラ  イドが必要  ==や!=などを使うと思ったら更に以下略  大小比較しよ...
タプルとの使い分けは・ ?                ・・タプル("山田 太郎", 20)   関数内に閉じていればタプルでいい   外部に公開するような関数の in/out はレ   コード   フィールドがたくさんある場合はレコード  ...
if-elif-else の嵐時刻と光の強さと雨の量から、天気を判断したい。  雨の量が 0    7 時∼17 時       光の強さが 5 以上なら晴れ       それ以下なら曇り    18 時∼4 時なら晴れ    それ以外    ...
愚直に実装すると・                     ・・let doSomething prec time luminance =  if prec = 0 then    if 7 <= time && time <= 17 then...
このコードの欠点似たような関数がいたるところに量産される
アクティブパターンに押し込めるlet (|Sunny|Cloudy|Rain|HeavyRain|)    (prec, time, luminance) =  if prec = 0 then    if 7 <= time && time ...
アクティブパターンの利点・欠点   ロジックをアクティブパターンに分離できた   doSomething の見通しが非常によくなった   パターンマッチによる網羅性のチェ      ック欠点としては、prec と time と luminanc...
型を導入するtype Weather =  Sunny | Cloudy | Rain | HeavyRainwith  static member Create prec time luminance =    if prec = 0 the...
型を導入した利点アクティブパターンと同じ利点に加え、順番を間違える可能性のある場所を、生成部分に絞れる組み合わせの数を掛け算から足し算に
match 式を活用する方向に進めるif-elif-else を書き始めたら危険信号when によるガード条件も同様match 式を使うために型をどんどん定義するその型を使う側でウマー
まとめBetter ○○を抜け出すには壁がある型を定義する壁を越えるために・   ・・  if-elif-else を使わない  when も使わない他の壁は各自越えていく感じで
Upcoming SlideShare
Loading in …5
×

Better C#の脱却を目指して

12,908 views

Published on

第二回関西関数型勉強会の発表資料です。

Published in: Technology

Better C#の脱却を目指して

  1. 1. Better C#の脱却を目指して bleis-tift November 24 2012
  2. 2. 自己紹介id:bleis-tift / @bleisなごや (こわくない)Microsoft MVP for Visual F#仕事は F#もやるけど、C#も
  3. 3. 対象関数型言語初心者を抜け出しつつある人
  4. 4. それなりによく見る光景今まで手続型の言語を使っていたチームで・ ・・C#の代わりに F#を使おう!(もしくは、Java の代わりに Scala を使おう!)→ C#や Java のコードを単に置き換えただけ
  5. 5. Better ○○便利になる部分はある。が、便利な○○どまり、と言うことも多いように思う。 「便利な○○」を抜け出すためには壁があると、思う
  6. 6. 壁の例 再帰関数の壁 高階関数の壁 カリー化、コンビネータ、関数合成の壁 型を定義する壁 各言語ごとのよりディープな壁パラダイムの壁を越えるのは大変・ ・・
  7. 7. 型を定義する壁C#や Java をはじめとする手続型言語では、型の定義が面倒 型をあまり定義しない習慣 プリミティブな型で済ませてしまうこの悪習を、F#などにも持ち込んでしまう結果、if-elif-else の嵐になるなど
  8. 8. C#での型定義User クラスpublic class User{ public readonly string Name; public readonly int Age; public User(string name, int age) { this.Name = name; this.Age = age; } public override bool Equals(object obj) { var other = obj as User; if (other == null) return false; return this.Name == other.Name && this.Age == other.Age; } public override bool GetHashCode() { return this.Name.GetHashCode() ^ this.Age.GetHashCode(); } public override string ToString() { return string.Format("User(Name={0}, Age={1})", Name, Age); }}面倒!
  9. 9. F#での型定義User レコードtype User = { Name: string Age: int}簡単!
  10. 10. 比べてみる C#では、ごてごてした修飾子が必要 C#では、コンストラクタでフィールドの初 期化が必要 C#では、Equals や ToString 等のオーバーラ イドが必要 ==や!=などを使うと思ったら更に以下略 大小比較しようと思ったら更に更に以下略F#は全部不要。簡単な値クラス程度のものならレコードを使えば十分。
  11. 11. タプルとの使い分けは・ ? ・・タプル("山田 太郎", 20) 関数内に閉じていればタプルでいい 外部に公開するような関数の in/out はレ コード フィールドがたくさんある場合はレコード F#の場合、||| > 演算子で扱えない、4 つ以上の タプルは極力使わないとか 型を定義してからロジックを書く 型駆動!
  12. 12. if-elif-else の嵐時刻と光の強さと雨の量から、天気を判断したい。 雨の量が 0 7 時∼17 時 光の強さが 5 以上なら晴れ それ以下なら曇り 18 時∼4 時なら晴れ それ以外 光の強さが 3 以上なら晴れ それ以外なら曇り 雨の量が 20 以上なら大雨 20 未満なら雨
  13. 13. 愚直に実装すると・ ・・let doSomething prec time luminance = if prec = 0 then if 7 <= time && time <= 17 then if luminance >= 5 then // 晴れ else // 曇り elif time <= 4 || time >= 18 then // 晴れ else if luminance >= 3 then // 晴れ else // 曇り elif prec >= 20 then // 大雨 else // 雨
  14. 14. このコードの欠点似たような関数がいたるところに量産される
  15. 15. アクティブパターンに押し込めるlet (|Sunny|Cloudy|Rain|HeavyRain|) (prec, time, luminance) = if prec = 0 then if 7 <= time && time <= 17 then if luminance >= 5 then Sunny else Cloudy elif time <= 4 || time >= 18 then Sunny else if luminance >= 3 then Sunny else Cloudy elif prec >= 20 then HeavyRain else Rainlet doSomething prec time luminance = match prec, time, luminance with | Sunny -> // 晴れ | Cloudy -> // 曇り | Rain -> // 雨 | HeavyRain -> // 大雨
  16. 16. アクティブパターンの利点・欠点 ロジックをアクティブパターンに分離できた doSomething の見通しが非常によくなった パターンマッチによる網羅性のチェ ック欠点としては、prec と time と luminance の順番を間違う可能性がある
  17. 17. 型を導入するtype Weather = Sunny | Cloudy | Rain | HeavyRainwith static member Create prec time luminance = if prec = 0 then if 7 <= time && time <= 17 then if luminance >= 5 then Sunny else Cloudy elif time <= 4 || time >= 18 then Sunny else if luminance >= 3 then Sunny else Cloudy elif prec >= 20 then HeavyRain else Rainlet doSomething weather = match weather with ...
  18. 18. 型を導入した利点アクティブパターンと同じ利点に加え、順番を間違える可能性のある場所を、生成部分に絞れる組み合わせの数を掛け算から足し算に
  19. 19. match 式を活用する方向に進めるif-elif-else を書き始めたら危険信号when によるガード条件も同様match 式を使うために型をどんどん定義するその型を使う側でウマー
  20. 20. まとめBetter ○○を抜け出すには壁がある型を定義する壁を越えるために・ ・・ if-elif-else を使わない when も使わない他の壁は各自越えていく感じで

×