SlideShare una empresa de Scribd logo
1 de 20
Descargar para leer sin conexión
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 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);
  }
}


面倒!
F#での型定義



User レコード
type User = {
  Name: string
  Age: int
}
簡単!
比べてみる


  C#では、ごてごてした修飾子が必要
  C#では、コンストラクタでフィールドの初
  期化が必要
  C#では、Equals や ToString 等のオーバーラ
  イドが必要
  ==や!=などを使うと思ったら更に以下略
  大小比較しようと思ったら更に更に以下略
F#は全部不要。簡単な値クラス程度のものなら
レコードを使えば十分。
タプルとの使い分けは・ ?
                ・・

タプル
("山田 太郎", 20)

   関数内に閉じていればタプルでいい
   外部に公開するような関数の in/out はレ
   コード
   フィールドがたくさんある場合はレコード
       F#の場合、||| > 演算子で扱えない、4 つ以上の
       タプルは極力使わないとか
   型を定義してからロジックを書く
       型駆動!
if-elif-else の嵐

時刻と光の強さと雨の量から、天気を判断し
たい。
  雨の量が 0
    7 時∼17 時
       光の強さが 5 以上なら晴れ
       それ以下なら曇り
    18 時∼4 時なら晴れ
    それ以外
       光の強さが 3 以上なら晴れ
       それ以外なら曇り

  雨の量が 20 以上なら大雨
  20 未満なら雨
愚直に実装すると・
                     ・・
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
    // 雨
このコードの欠点




似たような関数がいたるところに量産される
アクティブパターンに押し込める
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 Rain

let doSomething prec time luminance =
  match prec, time, luminance with
  | Sunny ->     // 晴れ
  | Cloudy ->    // 曇り
  | Rain ->      // 雨
  | HeavyRain -> // 大雨
アクティブパターンの利点・欠点



   ロジックをアクティブパターンに分離できた
   doSomething の見通しが非常によくなった
   パターンマッチによる網羅性のチェ      ック
欠点としては、prec と time と luminance の順番を
間違う可能性がある
型を導入する
type Weather =
  Sunny | Cloudy | Rain | HeavyRain
with
  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 Rain

let doSomething weather =
  match weather with ...
型を導入した利点




アクティブパターンと同じ利点に加え、
順番を間違える可能性のある場所を、生成部
分に絞れる
組み合わせの数を掛け算から足し算に
match 式を活用する方向に進める




if-elif-else を書き始めたら危険信号
when によるガード条件も同様
match 式を使うために型をどんどん定義する
その型を使う側でウマー
まとめ




Better ○○を抜け出すには壁がある
型を定義する壁を越えるために・   ・・
  if-elif-else を使わない
  when も使わない
他の壁は各自越えていく感じで

Más contenido relacionado

La actualidad más candente

君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
digitalghost
 
フィボナッチ数列の作り方
フィボナッチ数列の作り方フィボナッチ数列の作り方
フィボナッチ数列の作り方
Tomoya Kawanishi
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
 

La actualidad más candente (20)

C++ tips2 インクリメント編
C++ tips2 インクリメント編C++ tips2 インクリメント編
C++ tips2 インクリメント編
 
C++ tips1 #include編
C++ tips1 #include編C++ tips1 #include編
C++ tips1 #include編
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
フィボナッチ数列の作り方
フィボナッチ数列の作り方フィボナッチ数列の作り方
フィボナッチ数列の作り方
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
 
Ilerpg Study 004
Ilerpg Study 004Ilerpg Study 004
Ilerpg Study 004
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング
 
Map
MapMap
Map
 
Ilerpg Study 003
Ilerpg Study 003Ilerpg Study 003
Ilerpg Study 003
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
20150928楽しいlambda
20150928楽しいlambda20150928楽しいlambda
20150928楽しいlambda
 
言語処理系入門3
言語処理系入門3言語処理系入門3
言語処理系入門3
 
C言語講習会2
C言語講習会2C言語講習会2
C言語講習会2
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
Ilerpg Study 006
Ilerpg Study 006Ilerpg Study 006
Ilerpg Study 006
 

Similar a Better C#の脱却を目指して

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
CHY72
 
C#coding guideline その2_20130325
C#coding guideline その2_20130325C#coding guideline その2_20130325
C#coding guideline その2_20130325
Yoshihisa Ozaki
 
Phpではじめるオブジェクト指向(公開用)
Phpではじめるオブジェクト指向(公開用)Phpではじめるオブジェクト指向(公開用)
Phpではじめるオブジェクト指向(公開用)
VOYAGE GROUP
 
プログラミング学習のための学習
プログラミング学習のための学習プログラミング学習のための学習
プログラミング学習のための学習
siranon *
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
sunaemon
 

Similar a Better C#の脱却を目指して (20)

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
Processing
ProcessingProcessing
Processing
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
 
C#coding guideline その2_20130325
C#coding guideline その2_20130325C#coding guideline その2_20130325
C#coding guideline その2_20130325
 
C・C++用のコードカバレッジツールを自作してみた話
C・C++用のコードカバレッジツールを自作してみた話C・C++用のコードカバレッジツールを自作してみた話
C・C++用のコードカバレッジツールを自作してみた話
 
第1回勉強会スライド
第1回勉強会スライド第1回勉強会スライド
第1回勉強会スライド
 
Javascriptで無限ループを実現する5つの方法
Javascriptで無限ループを実現する5つの方法Javascriptで無限ループを実現する5つの方法
Javascriptで無限ループを実現する5つの方法
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
PHPMD, PHP_CodeSniffer x SideCIによる継続的コードチェック
PHPMD, PHP_CodeSniffer x SideCIによる継続的コードチェックPHPMD, PHP_CodeSniffer x SideCIによる継続的コードチェック
PHPMD, PHP_CodeSniffer x SideCIによる継続的コードチェック
 
async/await不要論
async/await不要論async/await不要論
async/await不要論
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
Phpではじめるオブジェクト指向(公開用)
Phpではじめるオブジェクト指向(公開用)Phpではじめるオブジェクト指向(公開用)
Phpではじめるオブジェクト指向(公開用)
 
仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプト仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプト
 
プログラミング学習のための学習
プログラミング学習のための学習プログラミング学習のための学習
プログラミング学習のための学習
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
 

Más de bleis tift

yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)
bleis tift
 
F#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリF#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリ
bleis tift
 
ぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLLぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLL
bleis tift
 
SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料
bleis tift
 
輪るビングドラム.NET
輪るビングドラム.NET輪るビングドラム.NET
輪るビングドラム.NET
bleis tift
 

Más de bleis tift (20)

PCさえあればいい。
PCさえあればいい。PCさえあればいい。
PCさえあればいい。
 
F#の基礎(?)
F#の基礎(?)F#の基礎(?)
F#の基礎(?)
 
No more Legacy documents
No more Legacy documentsNo more Legacy documents
No more Legacy documents
 
解説?FSharp.Quotations.Compiler
解説?FSharp.Quotations.Compiler解説?FSharp.Quotations.Compiler
解説?FSharp.Quotations.Compiler
 
効果の低いテストの話
効果の低いテストの話効果の低いテストの話
効果の低いテストの話
 
テストの自動化を考える前に
テストの自動化を考える前にテストの自動化を考える前に
テストの自動化を考える前に
 
札束でExcelを殴る
札束でExcelを殴る札束でExcelを殴る
札束でExcelを殴る
 
SI屋のためのF# ~DSL編~
SI屋のためのF# ~DSL編~SI屋のためのF# ~DSL編~
SI屋のためのF# ~DSL編~
 
F#事例発表
F#事例発表F#事例発表
F#事例発表
 
yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)
 
F#の基礎(嘘)
F#の基礎(嘘)F#の基礎(嘘)
F#の基礎(嘘)
 
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
 
VBAを書きたくない話(Excel-DNAの紹介)
VBAを書きたくない話(Excel-DNAの紹介)VBAを書きたくない話(Excel-DNAの紹介)
VBAを書きたくない話(Excel-DNAの紹介)
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 
自分戦略
自分戦略自分戦略
自分戦略
 
F#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリF#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリ
 
ぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLLぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLL
 
SCMBC闇LT資料
SCMBC闇LT資料SCMBC闇LT資料
SCMBC闇LT資料
 
SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料
 
輪るビングドラム.NET
輪るビングドラム.NET輪るビングドラム.NET
輪るビングドラム.NET
 

Better C#の脱却を目指して