このブログの中を検索する

ラベル デザインパターン の投稿を表示しています。 すべての投稿を表示
ラベル デザインパターン の投稿を表示しています。 すべての投稿を表示

2012/06/19

F#では変数を導入する箇所では常にパターン・マッチとなる

title: F#では変数を導入する箇所では常にパターン・マッチとなる
url: http://www.atmarkit.co.jp/fdotnet/special/introfs_02/introfs_02_01.html

snippet:
-----引用-----

「『let』の位置でパターン・マッチができる」とか、「関数の位置でパターン・マッチができる」(つまり、パターン・マッチは特別なもの)と考えるよりも、「『let』も引数もパターン・マッチしているのだ」と考えた方が自然だ。つまり、

let n = 42  // この「n」は変数パターン
let f x = x // 引数の「x」も変数パターン
「let」も引数も変数パターン

ということだ。このように、F#では変数を導入する箇所では常にパターン・マッチとなる。

これまで見たように、パターン・マッチを使うと、値からデータを取り出すコードが素直に書ける。さらに注目してほしいのは、値を作るときと同じ書き方で値を取り出せるという点だ。このように構築と分解を統一した表記で扱えるのも、パターン・マッチの特長だ。

-----引用-----

F# option型は「値がないかもしれない」ということを型として明示する

title: F# option型は「値がないかもしれない」ということを型として明示する
url: http://www.atmarkit.co.jp/fdotnet/special/introfs_02/introfs_02_01.html

snippet:
-----引用-----

最も厄介なのは、nullというのは(null許容型を除くと)型に現れないことだ。nullは参照型であればどんな型の値にもなり得る。そのため、null参照によるエラーというのは実行してみるまで分からない。これは、nullが来るかどうかの判定をプログラマーが抜け・漏れなく正確に管理する必要があるということを意味する。

それに対してoption型は「値がないかもしれない」ということを型として明示できる。さらに、string option型と、単なるstring型は全く別の型であるため、そのままではstring型として使えない(オプションを要素が1つだけ入るリストと考えれば分かりやすいだろう)。そして、string option型の変数から、中に含まれている値を取り出す場合は、常に値がない可能性を考慮する必要がある。

これらの特徴により、F#ではnullよりも安全に「値がないかもしれない」という事象を扱うことができる。次のコードは、string option型の変数を、string型として扱おうとしているコード例だ。このコードはコンパイル・エラーになる。

let x = Some "hoge" // string option型の変数「x」
// これはコンパイル・エラー
//let ans = x.IndexOf("o")
↑string option型の変数を、string型として扱おうとしてエラーになるコード例

-----引用-----

F#の判別共用体は、ある種のクラス階層を表すために使える

title: F#の判別共用体は、ある種のクラス階層を表すために使える
url: http://www.atmarkit.co.jp/fdotnet/special/introfs_02/introfs_02_01.html

snippet:
-----引用-----

F#の判別共用体は、ある種のクラス階層を表すために使える。

例えば、ファイルとディレクトリを判別共用体で表してみよう。次のコードがその例だ。

// 簡単のため、ファイルはファイル名とサイズのみを持っているとする
type FileSystemEntry =
  | File of string * int
  | Dir of string * FileSystemEntry list
↑ファイルとディレクトリを判別共用体で表した例

※定義した「FileSystemEntry」型を、Dirケースの値の型としても定義しているところがポイント。
このコードでは、「File」と「Dir」という2つのケースを持つ判別共用体としてFileSystemEntry型が定義されている。File/Dirケースの値の型は、「of」以下に記載されている。このコード例では、Fileケースが保持する型はstring型とint型であり、Dirが保持する型はstring型とFileSystemEntry型リストである(タプルの型のように見えるが、実はタプルそのものではない。単に、複数の型を持つことを意味する)。値の型の中で「FileSystemEntry型リスト」が使われることで、再帰的に判別共用体を格納できるので、ファイル・システムのツリー構造を表現できるというわけだ。

-----引用-----

F#でジェネリック関数を簡単に定義する

title: F#でジェネリック関数を簡単に定義する
url: http://www.atmarkit.co.jp/fdotnet/special/introfs_01/introfs_01_01.html

snippet:
-----引用-----

F#はこの「状態を持たない」方向に傾けたプログラムを書くためのサポートが手厚く、逆に「状態を持った」方向に傾けたプログラムを書くのが面倒になるように文法が構築されている。


F#は、ジェネリック関数も簡単に定義できる。例えば、

let gt x y = x < y
↑ジェネリック関数の定義例(F#)

とするだけで、C#での、

public static bool Gt<T>(T x, T y) where T : IComparable<T>
{
  return x.CompareTo(y) < 0;
}
↑ジェネリック関数の定義例(C#)

と同じようなものが定義できる。gt関数の型を推論するときに、比較演算子がジェネリックな演算子として定義されているため、gt関数の型も比較演算子同様、ジェネリックと判断されたのだ。

-----引用-----

Rを高速化するコーディング方法

title: Rを高速化するコーディング方法
url: http://www.anlyznews.com/2012/02/r_12.html
http://www.sciviews.org/benchmark/

snippet:
-----引用-----

1. パッケージや内部関数を使う

2. 行列演算 < apply関数 < ループ演算

対数尤度関数の記述方法と処理時間
記述方法 経過時間 行列演算比
行列演算 0.03秒 1倍
apply関数 0.48秒 16倍
ループ演算 1.11秒 37倍

6. 高速な数値演算アルゴリズムを選択する

数値演算アルゴリズムと処理時間
アルゴリズム 関数名 経過時間
GLM glm() 0.02秒
Newton-Raphson nlm() 0.03秒
BFGS optim() 0.04秒
L-BFGS-B optim() 0.04秒
Nelder-Mead optim() 0.06秒
CG optim() 0.45秒
SANN optim() 4.70秒
MCMC(Metropolis-Hastings) MCMCmetrop1R 9.61秒

7. whileよりもfor

-----引用-----

2012/05/22

銀の弾丸はない : 「AかBかどっちがいい?」みたいな質問の答えは、だいたい、「両方」もしくは「中間」になります = 中庸

title: 銀の弾丸はない : 「AかBかどっちがいい?」みたいな質問の答えは、だいたい、「両方」もしくは「中間」になります = 中庸
url: http://csharptan.wordpress.com/2011/12/25/net%e9%96%a2%e9%80%a3%e6%8a%80%e8%a1%93/

snippet:
-----引用-----

「AかBかどっちがいい?」みたいな質問の答えは、だいたい、「両方」もしくは「中間」になります。
  • GUICUIかと言われたら、両方。
  • 静的言語動的言語かと言われたら、両方。
  • ネイティブマネージかと言われたら、両方。
  • ウェブクライアントかと言われたら、両方。
  • オブジェクト指向型(OOP)関数型かと言われたら、両方。
それが現実です。
重要なのは、AとBそれぞれ、適切な利用場面がどこか、そして、選べるかどうかです。
「AもBも」といろいろ求められる昨今、AとB関係なく作れる部分と、そうでない部分をきっちりと分離しましょう。

-----引用-----

2012/05/21

メタプログラミングで何でもやろうとはしないでください。それは、汎用言語構文の役割です。

title: メタプログラミングで何でもやろうとはしないでください。それは、汎用言語構文の役割です。
url: http://csharptan.wordpress.com/2011/12/24/%e3%83%a1%e3%82%bf%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0/

snippet:
-----引用-----

メタプログラミングで何でもやろうとはしないでください。それは、汎用言語構文の役割です。
メタプログラミングは、汎用プログラミング言語の構文に漏れるような、ある特定の領域に対して特化した構文を作るのに使います。

「特定の領域に絞る」というのは非常に重要です。メタプログラミングで何でもやろうとはしないでください。それは、汎用言語構文の役割です。

-----引用-----

デザインパターンを言語機能化

title: デザインパターンを言語機能化
url: http://csharptan.wordpress.com/2011/12/24/%e3%83%a1%e3%82%bf%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0/

snippet:
-----引用-----

プログラミングには、「こういう場面はこう書くべきです」というようなパターンがつきものです。
「このパターン通りに書け」だと意識の高い人しか実践してくれませんが、「この文法使うと便利だよ」なら割とみんな使ってくれます。
C#にはそんな、パターンだったものを文法化したものがいくつかあります。

イベント
C#の場合、オブザーバー パターンに相当する機能は、イベント構文という専用の構文があって、1行で書けます。

public event EventHandler<int> Progress;

イテレーター
C#にはイテレーター構文というものがあって、このパターンを劇的に簡素化できます。以下の通りです。

public static IEnumerable<T> Where<T>(IEnumerable<T> source, Func<T, bool> cond)
{
    foreach (var x in source)
        if (cond(x))
            yield return x;
}

-----引用-----

2012/04/13

Code Contracts (現状のC#で非null保証をしたければ)


title: Code Contracts (現状のC#で非null保証をしたければ)
url: http://ufcpp.wordpress.com/2012/04/10/null%E9%9D%9E%E8%A8%B1%E5%AE%B9/

snippet:

-----引用-----
現状のC#で非null保証をしたければ、Code Contractsというのを使って、契約プログラミングします。Contractクラス(System.Diagnostics.Contracts名前空間)を使って、契約表明できます。

public static T Parse(string s)
{
    Contract.Requires(s != null);
    Contract.Ensures(Contract.Result<T>() != null);
    return new T(); // 仮実装
}

これで、Parseメソッドがnullを返さないことを保証します。

このRequiresやEnsuresメソッドは、実際には何もしない
Conditional属性が付いていて、コンパイル後に消える


静的検証
  • Visual Studio 2010に関しては、Code Contractsの別途インストールが必要
  • 有償エディションにしか入らなかったはず
  • その上で、コード解析オプションをOnにしないと働かない
  • 静的コード解析、そこそこ時間がかかる
動的検証
  • 静的解析しきれない部分を検証するために、動的検証コードを入れるオプションもある
  • 契約の表明はあくまで自己申告なので、やろうと思えば虚偽申告できる
  • Code Contractsに対応していないライブラリを使うと、必然的に何らかの動的検証が必要
  • この場合、(C#のコンパイル結果の)ILコードを書き換えて、検証コードを埋め込んでる
  • 契約違反は実行時例外発生
  • もちろん、検証コード分、実行時の負担になる
  • ちなみに、.NETの標準ライブラリには、.NET 4から、Code Contractsによる契約が表明されています。また、書いた契約をドキュメントに反映する仕組みも持っています。
-----引用-----

2012/04/06

アルゴリズムは静的メソッドで実装


title: アルゴリズムは静的メソッドで実装
url: http://csharptan.wordpress.com/2011/12/14/%e8%a6%8f%e7%b4%84%e3%80%81%e5%ae%9f%e8%a3%85%e3%80%81%e3%82%a2%e3%83%ab%e3%82%b4%e3%83%aa%e3%82%ba%e3%83%a0/

snippet:

-----引用-----
アルゴリズムをクラスのインスタンス メンバーとしてではなく静的メソッドで実装
特定のクラスのインスタンス メンバーとして実装するよりも、別途静的メソッドを用意した方が、依存関係がなくてすっきりします。
-----引用-----

2012/03/30

I/O待ち時間が長い処理は非同期実行


title: I/O待ち時間が長い処理は非同期実行
url: http://csharptan.wordpress.com/2011/12/10/%e9%9d%9e%e5%90%8c%e6%9c%9fio%e5%be%85%e3%81%a1/

snippet:

-----引用-----
I/O待ち(特に通信のレスポンス待ち)にParallelクラスを使おうとすると、大量のスレッドが作られます(これも環境次第ですが、私のところでは70個くらいのスレッドが立ちました)。
-----引用-----

-----引用-----
var tasks = Common.GetQueries(context, keys)
    .Select(x => x.ExecuteAsync()
        .ContinueWith(t => { lock (w) Common.Output(t.Result, w); })
    ).ToArray(); // ToArray を付けて、ここで全タスクを先に起動してしまう。
Task.WaitAll(tasks.ToArray());

待つだけのための無駄なスレッドはなくなります。I/O待ちキューは、「I/Oを待っている処理がある」という程度の小さい情報しか持ちません。
-----引用-----

2012/03/29

LINQデータ処理の方法 : IEnumerableとIQueryable


title: LINQデータ処理の方法 : IEnumerableとIQueryable
url: http://csharptan.wordpress.com/2011/12/09/2%e7%a8%ae%e9%a1%9e%e3%81%aelinq/

snippet:

-----引用-----
LINQ、つまりC#(やVB)のデータ処理の方法として、大まかにいうと以下のような2つの方式があります。
  • 内部加工方式: データ全件もらって、プログラム中で加工
  • 外部クエリ方式: クエリを投げて、外部のサーバー上で処理してもらって、結果だけ受け取る
C#的にいうと、LINQを、IEnumerableを使って書く(内部加工)か、IQueryableを使って書く(外部クエリ)かの差です。

Key-Valueストアのようなデータベースでは、書けるクエリに制限があるため、外部クエリと内部加工のハイブリッドな処理が必要になります。
  • C#なら、AsEnumerableを付けるだけで一発切り替え
  • ただし、AsEnumerableを付ける位置にはくれぐれも気を付けましょう
-----引用-----

2012/03/04

できる!並列・並行プログラミング

title: できる!並列・並行プログラミング
url: http://www.slideshare.net/pfi/ss-9780450

snippet:

-----引用-----
ロックのもたらすバグ・不具合一覧
  • アンロックし忘れ
  • デッドロック →つまり ロックの順番を同じにしなければならない
  • ロックの不足(Race Condition = 競合)
  • ロックの過剰(全然並列にならない)
  • モジュラリティの欠如 →つまり ロックを用いたプログラムを組み合わせることは不可能である
-----引用-----

エラー処理を書いてはいけない

title: エラー処理を書いてはいけない
url: http://research.preferred.jp/2011/12/do-not-write-error-handling/

snippet:

-----引用-----
  • リソース管理をしてはいけない →そこで RAII
  • ロック処理を書いてはいけない →そこで
    • メッセージパッシング
    • Software Transactional Memory(STM)
    • Concurrent Revisions
  • エラー処理を書いてはいけない →そこで モナド?
-----引用-----