飽きっぽい人のブログ

プログラマとしてもテスターとしても中途半端な人のブログ

TypeScriptで疑似的な文字列enumを作る

※2015/09/24追記 やはりいろいろ問題があるようなのでこの方法は使わないほうが良いです。

知っての通り、TypeScriptのenumには文字列を設定することはできない。
下記のようにすればenumのメンバ名の文字列を取得することはできる。(TypeScript1.6を使用)

export enum Fruits {
    BANANA=1,
    APPLE=4,
    ORANGE=5
}


export function showFluits(fruits:Fruits){
    //これで文字列をとりだせる
    let fruitsStr = Fruits[fruits];
    console.log(fruitsStr);
}


showFluits(Fruits.APPLE);//APPLEと表示される

しかし文字列を定数として扱うことのみを考えた場合、TypeScriptのenumではやや冗長すぎるJavaScriptが生成される。

生成されたJavaScript

export var Fruits;
(function (Fruits) {
    Fruits[Fruits["BANANA"] = 1] = "BANANA";
    Fruits[Fruits["APPLE"] = 4] = "APPLE";
    Fruits[Fruits["ORANGE"] = 5] = "ORANGE";
})(Fruits || (Fruits = {}));
export function showFluits(fruits) {
    //これで文字列をとりだせる
    let fruitsStr = Fruits[fruits];
    console.log(fruitsStr);
}
showFluits(Fruits.APPLE); //APPLEと表示される


const変数やオブジェクトリテラルを使用してもよいのだが、それだとせっかくのTypeScriptの型の恩恵を受けることができない。
showFluits関数の引数fruitsがstring型になった場合を考えてみてほしい。その関数を使うユーザは何の文字列を引数にしてよいか戸惑ってしまうだろう。
それで型の恩恵を受けつつ文字列定数を定義する方法はないか考えた結果以下のようになった。

export interface Fruits extends String{}

//インターフェースと同じ名前の名前空間
export namespace Fruits{
	export const BANANA:Fruits="BANANA";
	export const APPLE:Fruits = "APPLE";
	export const ORANGE:Fruits = "ORANGE";
}

export function showFruits(fruits:Fruits){
	console.log(fruits);
}

showFruits(Fruits.APPLE);//APPLEと表示される

生成されたJavaScript

export var Fruits;
(function (Fruits) {
    Fruits.BANANA = "BANANA";
    Fruits.APPLE = "APPLE";
    Fruits.ORANGE = "ORANGE";
})(Fruits || (Fruits = {}));
export function showFruits(fruits) {
    console.log(fruits);
}
showFruits(Fruits.APPLE); //APPLEと表示される

まあ若干裏技感があるんだけどね。

C# for Systems Programming Part2 fail fast

C# for Systems Programmingの情報がJoe duffy氏のブログで新しいのが書かれていたので和訳してみます。例によってGoogle翻訳を使っての拙い訳です。

-----------------------------ここから和訳-----------------------------

If you’re going to fail, do it fast

私たちの言語開発チームで検討した技術の一つは"fail-fast"と呼ばれるもので、プログラムが可能な限り迅速にバグが検出された後に失敗するというアイデアだ。このアイデアは本当にフィクションなどではなく、現実的なアプリケーションなものだ。多分ね。

下記のものは私たちが開発中のシステムでfail-fastとなるものである。

・契約違反(Contract violation)

・実行時宣言違反(Runtime assertion violation)

・Null参照先のデータ取得(Null dereference)

・メモリ不足(Out of memory)

・スタックオーバーフロー(Stack overflow)

・ゼロ除算(Divide by zero)

・算術オーバーフロー(Arithmetic overflow)

もしあなたが.NETで投げられた例外の内の90%を見て、それらが上記の状況によるものである。これは面白い。

これは例で、開発中のシステムに似たものだ:

これは最終的に以下のようになる。

私の経験では開発者はふつう、以下の二つの失敗状態の反応により、一つを行うことで終了する。

1.キャッチして続行する。一般的にはバグを隠ぺいし、それが難しく後で検出するために行う。

2.プロセスをクラッシュさせる。その後スタックは戻されて実行が終了する。潜在的に重要なデバッグ状態は失われる。

私は合法的キャッチして例外を処理する3番目があると仮定したが、それは珍しいものでリストに上げたくはない。それらは通常プログラミングのエラーであり、キャッチされるべきでまた容易だ。"キャッチして無視"の規律は莫大な壊れたウィンドウとなる。

例外はその場所を持っている。しかし、入出力、データ、の残り10%のシナリオについては再スタート可能だ。(例:パーサなど)

私たちが既存のコードベースにfail-fastを適用したときには案の定多くのバグを見つけることができた。これは例外ベースの事故にはふくまれていないが、常に返値ベースのものだ。私たちが移植したのは音声サーバのプログラムだった。それは数年前からHRESULTが内包されていたルーチンで実装されていたが誰も気づいてなかった。悲しいことにこれが台湾の顧客は80%のエラーに見舞われた。fail-fastはそのエラーを私たちに対面させた。

このカテゴリに算術オーバーフロー(Arithmetic overflow)をいれることにあなたは疑問を抱くだろう。その通りで、私たちはデフォルトで計算チェックを使用している。興味深いことに、これは私たちが遭遇した障害のなかで共通して最もストレスの元となったものだった。(おかげで大部分がfail-fastとなるだけでなく、競合状態やデッドロックを排除して、安全な実行モデルとなる。・・・しかし私は脱線する)。なんて腹立たしいことだと言うかもしれない?まさか! ほとんどの時間は開発者が実際のところオーバーフローが可能であるなんて期待していなかったし、無言のラップアラウンドは偽の結果をもたらすだろう。事実、共通のセキュリティ開発の元は今日、整数オーバーフローをトリガーすることにより得られる。最善は開発者にそれをスローして対面させること、そして、その開発者にチェックをはずすかどうか決めさせることだ。

メモリ不足(Out of memory)は別のケースだから横に置いておこう。現代のアーキテクチャは障害をさける方法をとるよりかは、むしろ、障害を容認する傾向がある(例:再スタートできること、状態を書き込めることなどなど)。そう、オブジェクト指向モデリング硬化が時間とともにどんどん珍しくなる傾向になっている。それゆえ、fail-fastのデフォルトは実際ほとんどのコードにおいて正しいものだ。しかし、いくつかのサービスに--カーネル自身のような--は不適切なのかもしれない。私たちがどのようにこれに取り組んだかはブログ投稿を見てほしい。

.NETは既にfail-fastを選択的に使用している。このように"corrupted state exceptions”

私たちは積極的により広く、C#と.NETへのfail-fastの規律を適用し、調査している。だから、期待してほしい。しかしながら、幅広いプラットフォームのサポートがない場合にはその規律があなたのコードベースで簡単に採用できるのだ。

-----------------------------ここまで和訳-----------------------------

方針としてはやって当たり前なチェック処理は既定でやるようにして、必要に応じてそのチェックを外せるようにするみたいですね。このあたりがC++とは違うのでしょうか。 まあ、算術オーバーフローの項のuncheckedはC#にすでにあったと思いますが。

例にでてたrequires構文?はD言語のin契約に似ている印象(D言語まともにやったことないけど)。というかこれC#にも欲しい機能です簡潔に引数チェックできそうですし。

気になっていたメモリ管理についてはノータッチだったのでこの言語の評価はまだ何とも言えないですね。少し前の記事でクラス実装終わったみたいなこと書いてたんでぼちぼち情報が出てくるんじゃないでしょうか。とりあえずお蔵入りになってなくてよかったです。

Microsoftが研究中の新言語について思うこと

昨日書いたM#ネタ(C# for Systems Programingとも。ながいのでこの記事ではM#とします)の続き。昨日は訳を上げるだけで力尽きたので思ってることを書いてきます。

新しいOSを記述するための言語

M#は中間言語(非JIT)を出力する言語で、これまたMicrosoftで研究中のOSであるMidoriを記述するために開発が始められたそうです。
C++の代わりにこれ使うぜ!みたいなノリですね。ようはMicrosoft版DやGoと思ってもらえれば。
ただ、最初からOSを書くことを目的としているだけあってGCに依存しない言語仕様になるようです。また一方でWebサービスを提供できる程度のポテンシャルを持っているとか。
それだったらGC使う道筋もほしいなあと思うけど、言語仕様についてはまだほとんど公開されていないのでこうだとは決めつけて書けないのがなんとも。

ぶっちゃけいるの?

「古いC++を捨てて、新しくきれいに設計された言語を使おう!」というのはやや安直な気はします。
正直俺はC++の言語仕様(C++11以降)も結構気に入っていて、レガシーな部分を引きづっていますが結局のところ言語仕様というのは月日が経つとどうしても汚くなっちゃうんじゃないかなと思います。 これはソフトウェアの技術革新が起こり続ける限りしょうがないことじゃないでしょうか。なので新しく設計された言語を使ってもいずれは汚くなって意味なくなるんじゃないかなと思っています。
ただ、Microsfotとしては必要なのではないでしょうか。
というのも今までC++/CLIC++/CXといった標準のC++言語仕様から逸脱した拡張をやってきたわけで、 それが続くとC++標準化の進行妨げになるか、あるいはいずれC++標準化委員会からMicrosoftが見捨てられるかのどちらかに行っちゃうんじゃないかなと思います。
それでまあ、M#の言語機能にMicorosoftが独自に盛り込みたい機能をつければ、MicrosoftC++に対していらん拡張しなくなってC++側にもメリットはあるんじゃないかなと。
当然C++の覇権は薄れますが、さすがに全てのコンパイラの面倒を見る以上、Microsoft固有の事情には構っていられないわけで、仕方のないことじゃないですかね。
例えば、最近公開された.NET Nativeのようなクラウド上のコンパイルに密接に言語仕様を絡めたプログラミング言語を提供したいと思ったときに、C++が対応してくれるかといったらそうじゃないと思うんですよ。
俺個人としてもこのクラウド上のコンパイルにはいろいろ可能性があるかなと思っていて、そういう意味においては今更感のあるMicrosoftの新言語開発を応援してる、といったところです。

ま、お蔵入りするかもしれないんですけどね(^q^)

C# for Systems Programming

リーク情報ではM#とも呼ばれているマイクロソフトが開発中のC#をベースとした新しい言語らしいですね。
すでにM#という全くの別物が存在します。関係ないですが
去年の暮れぐらいに公開された中の人のブログでは、今年の半ばぐらいになんらかの情報開示がされるとのこと。まあお蔵入りになる可能性も高いですが
なんとなく和訳したくなったのでしてみました。といってもGoogle翻訳頼みなので英語読める人は原文読んだ方がいいと思います。
原文のブログ:C# for Systems Programming
尚、訳注は[]で括った中に書くものとします。

--------------------------------------------------------------------------訳ここから--------------------------------------------------------------------------
このブログはいくつかのコミュニティの対話を容易にするための投稿がかなり多くなっている。

私の履歴からすれば明らかなように、私の研究生活は[プログラミング]言語であると説明される。それ以外の何物でもない。
MSR[マイクロソフトリサーチ?]の者として考えれば文書公開は私のブログではなくPLDIへ提出手続きするのが妥当だ。
私は単にこのような論文が受理されて取得するのに十分な才能がないだけだ。

私は、何らかの"深い意味"か"手がかり"だからではなく、オープンな精神で全てのコミュニティの連携の書き込みを今後数ヵ月で期待していますが、それは既に進行中かもしれません。あまりにも多い憶測だ![訳が微妙]

私は熱意を見るのが大好きだから、今後来る技術的な対話の場を保管してほしい。他の思惑は静かな死を迎え、私は幸せになるだろう。

私のチームは過去4年間C#に"システムプログラミング"拡張の設計と実装を行っている。やっとのことで、私はブログ記事のシリーズで経験を共有することから始めるだろう。

第1の疑問は"なぜ新しい言語なのか?"だ。私はすぐに、世界は言語を過度に持っていることを認めるだろう。

理由は次の通りだ。
もしあなたが"安全性と生産性"と"パフォーマンス"を軸として主要言語の範囲を描く場合、あなたは以下のようなものを描くかもしれない。

f:id:qwerty2501:20140504234730p:plain

(これは話半分に聞いてほしいのだが、私は多数の安全性の種類があるなどのことによって、安全性と生産性(それらは確かに連携しているけれども--どの程度の時間と労力を見るかは、一般的に安全なバグ、lintツールなどと一緒にすごすかだ。)が等価ではないと理解している)

まあ、私は今日の言語コミュニティは4分割された領域の内、2つの大きな領域に支配されていると主張している。

図の左上の領域についてだが、開発者の生産性を重視し、ガベージコレクションを備えた言語がある。
過去数年にわたり、Googleが先導して方法と何ができるかを見せてくれたおかげで、JavaScriptのパフォーマンスが劇的に改善している。
最近ではみんながPHPと同じことをしてきた。動的型付け言語ファミリ全ては現在与えられているC#Javaのように彼らの金のために実行されているのは明らかだ。[訳が微妙]
現在の選択肢は、パフォーマンスを控えるか、より多くの静的型システム望むかということになる。
これは、C#のような言語がますます排中律に苦しむ苦しむことになる。真ん中は悪い場所ということだ。

図の右下について、パフォーマンスに対して最大限の努力を発揮することができる。
正直、ほとんどのプログラマは図のこの領域にC#Javaを置かないだろうだろう、私も同意見だ。
多くの人々が苦い思いをしてガベージコレクションからC++に逃げ戻ったのを私は見てきた。(公平を期すために、これはガベージコレクション自身の部分的なものだけだ。それは主にデザインパターンが貧弱だったり、フレームワークだったり、言語での改善機会の喪失によるところが大きい。)
Javaはコードのピッチングとスタック割り当てを採用したHotSpotのような仮想マシンでの素晴らしい働きにより、よりC#に近い。
しかし未だに、ほとんどのハードコアシステムプログラマはパフォーマンス上のアドバンテージのため、C#JavaよりもC++を選択する。
C++11では生産性と安全性の分野でC#Javaのような言語に近い調整が行われたにもかかわらず、それはC++に型安全性の保障を追加するための明示的な目標ではない。最近では危難に遭遇するのは減少したが、私は妊娠と同じように、"あなたを半端な安全にすることはできない"と固く信じている。
その存在はあなたが常に最悪のケースを想定し、型システムが持っている安全性よりも事後の安全性を回復するためのツールの使用する必要があることを意味している。

私たちのトップレベルの目標は、本当に図のこれらの領域の間で選択する必要があるかを探ることだった。つまり、右上のどこかにスウィートスポットがあるのかということだ。
巨大なコードベースにこれを適用するなどをして数年の作業の後、私はその答えが"Yes!"であることを確信している。

その結果は完全に新しい言語より --最小限の破壊的変更を施した-- C#の拡張セットの詳細を見るべきだ。

次の疑問は"なぜC#をベースにしたのか?"だ。型安全は私たちが希望する言語の譲れない機能だ。
そして"現代的で型安全なC++"としてキャンバス上に描き始めるにはC#が滅茶苦茶良かった。
特にラムダやデリゲートといった現代的な機能が存在するため、Javaよりは私たちが望むものに近い。
最近ではD,Rust,Goなど多数の言語が候補としてこの場に挙げられた。
しかし私たちが始めた時にはこれらの言語はまだ十分に表面化していないか、もしくは私たちが焦点している意図した領域にまだ投資がされていなかった。
それとまあ、私のチームはマイクロソフトで働いており、ちょうど手の届く範囲内に特に顧客をベースに十分なC#の才能とコミュニティがあった。
もちろん、これら他の言語コミュニティの専門家との協力を熱望しているし、すでにいくつかの重要な人々とアイディアを共有している。
良いニュースなのは、CやC++,Haskellそして深い型システムを起源とする私たちの系譜が分野領域で働いていることなどがあげられる。

最後に、"なぜC++ベースにしないのか?"とあなたは不思議に思うだろう。
ここまでに述べたように、私は多くの場合、私たちがC++で開始する必要があるかどうかを疑問に思うし、言語の"安全なサブセット"を切り開くのとは逆方向に働いた。
私たちは"ミキサーの中にC#C++を投げ入れて何が出てくるかを見て、"そしていつもC#が私たちによって引き止められるのを認めるだろう。
特に、あなたがRAII、決定的な破棄、参照、その他ジェネリックとテンプレートの対比について考え始めることで絶妙なブログ投稿となる。[このあたりも訳が微妙・・・]
私は教訓を得ることといずれ手段を探ることを期待している。主に以下の二つの理由による。
(1):それはより多くの開発者(地球上にはC#開発者よりもC++開発者の方が多数いる)のために移植性を容易にする
(2):私はOSSコミュニティが困難な"安全性と生産性 VS パフォーマンス"の決定を常にする必要がないように、アイデアを標準化するのが夢だからだ
しかし、最初のプロジェクト目標のために、リッチな.NETフレームワークを設計図として使用するといった理由ではなく(私たちの目標のためには重い変更が必要であると指摘されている)、C#で始まったことに満足している。

私は長年の仕事にわたって、いくつか気付いたことがあった(例として、ここここを見てくれ)。
今後数ヵ月で、私はより多くの細部の共有を始めるだろう。
私の目標は最終的にはこのことをオープンソースにすることだが、言語のいくつかの側面について話をやめる必要があり[訳が微妙]、また、より重要なことでRoslynへのコードベースでの移行が必要になる。そのため、C#との関連性はよりエレガントになる。うまくいけば2014年に。

高レベルの目標では、以下の6つの主要なカテゴリに言語機能を分類した。

1) Lifetime understanding
C++はRAII、決定的な破壊[デストラクタ?]、およびオブジェクトの効率的なアロケーションを持っている。C#Javaは開発者をうまく扱ってGCヒープにあまりに大きく依存させているが、IDisposableを経由して、決定的な破壊のための唯一の"ゆるい"サポートを提供している。
私たちのチームのやることの一部は、定期的にC#をこの新しい言語に変換することだ。そして、私たちに30~50%のGCにかかる時間に遭遇することが珍しいことではなかった。
サーバーの場合、これはスループットを殺す。クライアントの場合は、それが対話の待ち時間が入ることによってエクスペリエンスを劣化させる。
我々にはC++から盗んだ記録がある。 --右辺値参照、ムーブセマンティクス、破棄、参照/借入のような領域において-- そしてまだ安全性の必要な要素を保持し、関数型言語からのアイデアでそれらを統合した。
これは、積極的にオブジェクトはスタックアロケーションし、確実に破壊し、より多くのことができる。

2) Side-effects understanding
これはOOPSLA 2012で公開された革新的なもので、第一クラスの普遍性と隔離と一緒にC++const(を安全にしたもの)を与える。

3) Async programming at scale
コミュニティは継続渡しや軽量ブロックコルーチンを使用するかによって堂々巡りをさせられてきた。
これはC#だけでなく、地球上のほとんど全ての言語が含まれている。
ここでの重要な技術革新は、実行モデルにとらわれない構成可能な型システムであり、いずれかに効率的にマッピングすることができます。
それは我々がこのようなものを正しい方法で公開しなくてはならないという傲慢だが、他の多くのアプローチ経験を持つ私にとって大好きな着地点だ。

4) Type-safe systems programming
型安全はパフォーマンス固有の消失になるという主張だ。
それは、境界チェックが譲渡禁止であり、我々は既定でオーバーフローチェックを好むということは事実である。
JITコンパイラと比較して良い最適化コンパイラはこれに対して何ができるかは驚愕的だ。(これらの機能でメリットがあるのは、いくつかの最近のセキュリティ情報を監査必要がある)
他の領域ではアロケーションなしに多くを行うことができるように含まれている。(委譲や表示のためというよりはむしろ)アロケーションなしで呼び出すことができる、ラムダベースのAPIを持っているようだ。
そして、アロケーションなしで容易にサブアレイ及びサブストリングを切り開くことができる。[所有権を持たない配列や文字列を指しているのだろうか]

5) Modern error model
これはコミュニティが同意しないものの一つだ。私たちは私が信じる以下のようなスウィートスポットを選んだ。
至る所での契約(事前条件、事後条件、不変条件、アサーションなど)。
fail-fastを既定のポリシーとする。
例外は珍しい動的な失敗のものとする(I/O構文解析など)。
型付けされた例外は絶対に必要とするリッチな例外のみ。
動作を安全かつ健全にするために、全ての適切な必要動作を取得するように、第一クラスによる型システムに統合されている。

6) Modern frameworks
これは、非同期LINQ、パフォーマンス上のC++イテレータと競合と要素の抽出のために二重のインターフェース要求しない改良列挙子のサポートなどといったものをカバーする包括的なバケツだ。
ぶっちゃけ、これは我々がもっている"設計されたが、まだ実装されていない"リストの一番大きなもので、void-as-a-1st-class-type[第一クラス型としてのvoid]、non-null types[非null型]、traits、 1st class effect typing[第一クラスの効果型?]などがある。
私たちが2014年半ばに一部を持っていることを期待するが、そう多くはないだろう。

興味があるなら、私はあなたがどう思うか全体的な考え(だけではなく具体的にも)について聞くことを熱望している。また、側面の人々にはさらに詳細を聞きたい。
私は共有することに興奮している。しかし、現実には今後数ヵ月で書くのには多くの時間を持っていない。
我々がやらなければいけないことは大量にある(ま、人材募集中てことだ[原文にメールリンクあり])。
だが私はなにを共有し、どのような順序で優先順位を決定するかの補助のために、確実に君たちが好きだ。[訳微妙]
最終的に我々が実際のコードを共有する日が来ることを熱心に待っている。それまではハッピーハッキングだ!

Windowsのこれからを占う 事前コンパイルを最大限に活用するOSへ

はい、占ってみようと思います
こういうこともWindows9に関する情報が出そろっていない今が旬かなということでw

.NET Nativeからどう進むのか

以前拙ブログでも.NET Nativeの記事を書いたのですが、今回の記事でも少し関係があるので要点だけ書きます

.NET Nativeの特徴
・.NETのアプリケーションの事前コンパイル
・インストール時には既にネイティブアセンブリとなっており、フレームワークが静的にリンクされる

ポイントは.NETフレームワークが静的にリンクされている点でしょうか。そのため、事前コンパイラにより最大でOSのAPIを直接呼び出すまで最適化されます(はずです)
今回はこのあたりに注目していきたいと思います

これ、Bartok

はい、そう思った方はかなりのMicrosoft好きですねw
Bartokについて知らない方が多いかと思いますので、補足するとBartokとはMicrosoftが研究開発していたSingularityというOSに付属する事前コンパイラらしいです
詳しくはSingularityの資料を見ていただきたいのですが、資料内にわかりやすい図があったので乗せときます

f:id:qwerty2501:20140426204155p:plain

.NET Nativeの事前コンパイルの仕組みにそっくりですが、どうも資料を見る限り、Singularity OSのカーネルまでもが静的リンクの対象に含まれているように見えます
それもそのはずで、SingularityのほとんどのコードがC#の言語仕様に破壊的な変更を加えた言語で書かれており、中間言語として出力されるためです
そのため、今まで関数の呼び出しとして提供されてきたOSのAPI呼び出しが、事前コンパイルの最適化により、インライン展開される可能性を秘めているのです
これによりかなりアプリケーションの高速化が期待できます 2006年のものですがベンチマークの資料があったので乗せときます(ソース)

f:id:qwerty2501:20140426211003p:plain

クラウド上で新OSのAPIを提供か

Singularityのように中間言語で提供すれば理論上は可能なはずです。.NET Nativeの登場により現実性が一層増しました
ただし、全てを静的にリンクしてしまうとさすがにアプリケーションが肥大化しすぎてしまうので、最小限のカーネルはクライアントにインストールされるのが妥当な線ではないでしょうか
もちろんすぐに、とはならないでしょう。OSのAPIを新しく書き直さないといけませんので
また、この手の最適化はストアアプリのようなアプリの配布を管理できるプラットフォームに限定されるのではないでしょうか。でないとOSのAPIやプラットフォームに更新が入ったときにいろいろめんどうそうです
いずれにせよ、実現すればアプリケーションのかなりの高速化が見込めます
Windows PhoneやWindowsタブレットの今後に期待といったところでしょうか

async/await ~非同期なライブラリは楽じゃない~

※個人的な備忘録的なものです。 こっちとかこっちのが良くまとめられています。
ライブラリ制作者向けの内容になっているのでアプリ製作者にはあまり関係がないかもしれません なお、サンプルコードは全てWindowsストアアプリとして実行したものとします

デッドロックで泣きを見ないように

下のようなライブラリのコードがあるとします

gist11215254

このライブラリのDoAsyncは呼び出され方によってはデッドロックされてしまいます
下のコードがその例になります

gist11215568

原因はTaskのWaitメソッドでロックしたスレッドに対して、HeavyWorkAsyncメソッドでワーカースレッドで作業していたTaskが元のUIスレッドに戻ろうとしたためです
図にすると以下のようになります

f:id:qwerty2501:20140424220821p:plain

Waitするなと思った方がいらっしゃるかもしれませんが、使用するのは自分ではなく他人のアプリ製作者(もしくは自分のライブラリを使用してさらにライブラリを制作しようとしている人)になりますので、そのような命令をすることはできません
この問題を解決するにはDoAsyncの実装を下のようにします

gist11215506

こんどはHeavyWorkAsync().ConfigureAwait(false)の戻り値をawaitしていますね Taskを直接awaitするとConfigureAwait(true)を規定で呼び出すらしいです
引数のbool値についてですが、trueを渡すと呼び出した時点のスレッドの同期コンテキストを使用してもとのスレッドにTaskの処理を戻そうとします。falseを渡すと処理が行われたスレッドでそのまま続行します
実装をHeavyWorkAsync().ConfigureAwait(false)に変更した場合の図は以下のようになります

f:id:qwerty2501:20140424224909p:plain

そもそもこのような一行の呼び出しではawaitする必要はないかと思います
ただし、非同期処理の例外をキャッチしたい場合はConfigureAwait(false)したものをawaitする必要があります

全てConfigureAwait(false)すれば良いのか

そこが非同期プログラミングの難しいところで、非同期プログラミングにおいては「大体これでいいけど例外が存在する」というのが多いようです
taskオブジェクトをConfigureAwait(false)するのもそれに倣っており、ライブラリ内の非同期実装は大体ConfigureAwait(false)で取得した待機オブジェクトをawaitすればよいのですが、ユーザに対するイベント通知を行う場合には注意する必要があります
下のようなコードについて説明します

gist11217368 このクラスのSomeEventHandlerの通知によってライブラリユーザがUIの更新をすることが高いと予想されるケースです。 この様なケースではSomeEventHandler呼び出し時にUIスレッドに戻っていることが望ましいでしょう
DoAsync内ではHeavyWorkAsync()の呼び出しをConfigureAwait(false)で取得した待機オブジェクトでawaitしています
その後、SomeAsyncは規定のawaitで待機しています
この場合、SomeAsyncでは既定のawaitを行っているのでUIスレッドに戻りそうに見えますが、実際にはSomeEventHandlerを呼び出す時点ではUIスレッドとは別のスレッドになっています。これは事前に呼び出したHeavyWorkAsyncのタスクをConfigureAwait(false)した時点でUIスレッドには戻らないためです
そのため、SomeAsyncのタスクを規定のawaitで待機してしまうのは無駄にスレッドをロックしてしまうことになります。

SomeEventHandlerをUIスレッドで呼び出すには下記のようにします

gist11217686 awaitする前に同期コンテキストをキャッシュしておいて、SomeEventHandlerの呼び出しを同期コンテキストで切り替えてあげればSomeEventHandlerをUIスレッド上で実行することが可能です

しかし、このような対策を行ってもライブラリユーザ側で下のような使われ方をすると意味がありません

gist11218041 DoAsync呼び出し前に別のタスクをConfigureAwait(false)したものをawaitで待機された場合、DoAsyncの呼び出し時点ですでにUIスレッドではないため、DoAsync内で同期コンテキストを使って動作スレッドの切り替えを行っても無意味となってしまいます
この様にイベント通知をUIスレッド上で呼び出すのは難しいです。また、同期コンテキストによるスレッドの切り替えはかなり重いコストがかかるので自分のライブラリが同期コンテキストによるスレッドの切り替えを必要としているかよく吟味する必要があります(特にサーバーでも使われるライブラリの場合は不要な場合が多い)

まとめ

・基本的にはライブラリ内でawaitする場合はConfigureAwait(false)すること
・ConfigureAwait(false)すると元のスレッド(主にUIスレッド)には戻らないので、必要であれば同期コンテキストによる動作スレッドの切り替えを行うこと
・同期コンテキストによる動作スレッドの切り替えの要否はそのライブラリのコンセプト及び設計に基づいて決めること

非同期ってやっぱり難しいですね
うまく付き合っていくしかないかなあとは思いますが、ほかの言語だとどうなんでしょう
楽なのかな

ライブラリを公開するときにできるだけ無制限なライセンスにしたい

楽にライブラリを使用してほしい

こんばんわ、皆さんはライブラリを公開したことがありますか?
公開するときにはどんなライセンスを選んでますか?
修正BSDライセンス? MITライセンス? GNUなひとはGPL v3でしょうか。
俺としてはできるだけ制限をかけたくないので2条項BSDライセンスかMITライセンスで配布するのが安定かなと思っていたのですが、
これらのライセンスでも再配布の際には著作権表示をソフトウェアの重要な部分に記載しなければなりません。
たとえ他の人でも自分の著作権表示を書いてる姿を想像するとなんかもうめんどくさくなってきますよね
それで、もっと緩いやつないかなと思って探していたんですが、ちょうどいい感じのがあったんで紹介したいと思います。

著作権表示を求めないライセンス

2つ見つけました。一つはWTFPL、もう一つはNYSLです。
どちらも名前がふざけていますがいい感じのライセンスですねシンプルだし。
欠点といえばマイナー故に採用しづらいという点でしょうか。まあ個人開発なら問題なさそうです。
将来的に企業が使うことが想定されるソフトウェアでもとりあえずNYSLで公開しておいて、プロジェクトがある程度軌道に乗ったらApache Licenseなどに切り替えれば問題なさそうですね。

慣例的に行われている著作権表示が面倒だと考えている人は一度採用を検討してみてはいかがでしょうか。