Archive for 10月 2012
Windows Phone
Windows Phone 8 SDK
//build/ でも発表されましたが Windows Phone 8 SDK がリリースされました。
実機がないので WP8 アプリを書く気にもれなないんですが、単純に今までの WP7.1~7.5 用としても、今までの WP7 SDK は VS 2012 に対応してなかったので、新しい SDK が必要でして(VS 2010 を入れなおす気ははあんまりない)。
↑WP 7.5、世の中一般に出回ってるわけでもないですが、手元の自分用ツールを久々に更新してみようかと。
Portable Class Library
ただ、その、自分用ツール、機能の大部分を Portable Class Library に移しちゃってたんですよねぇ。 .NET 4.5 & .NET for Win Store 向けに。そして、もちろん、async/await 使いまくり。
WP8 では、普通に Task クラスも async/await も使えるようになっています。が、この自分用ツールは WP 7.5 向け…
てことで、
これの出番かと。
async/await が、 .NET 4、Silverlight 4、WP 7.5 でも使えますというふれこみ。つまるところ、Async CTP 時代と同じもの。そして今回重要なのが、
- and portable class libraries targeting those platforms (これらのプラットフォームを対象とした PCL でも使えます)
自分用ツールは WP 7.5 なわけで。解決したと思ったんですが…
やってることが Async CTP 時代と一緒なので、Task.FromResult とか Task.Run みたいな、静的メソッドがないんですよね。代わりに TaskEx.FromResult とか TaskEx.Run。クラス名が…
静的メソッドに対して拡張メソッドみたいなことしたいという要望が時々出てるのは知っていたものの、こういう状況で欲しくなるのよなぁ…
Compiler in the Cloud
以前から(プライベート リリースの時点から)話題にはなっていましたけども、結構すごいことしてますよねぇ。
これの、「Much faster code with “Compiler in the Cloud”」のところを見てもらっての通り、ストアのサーバー上で CIL を ARM ネイティブ コード化。実際には MDIL(Machine Dependent Intermediate Language)とかいう形式らしいので、全部が全部 ARM ネイティブ コード化ってわけでもないのかな(それとも、ARM ネイティブ コード + メタデータなのかな?)。
デスクトップ/Windows ストア アプリの方の .NET 4.5 でも、Ngen(実行前のネイティブ コード化)が自動的に(Windowsサービス使って定期メンテ)実行されるようになってるし↓。
もうさすがに、「JIT のコストがもったいないから中間言語方式はダメだ」とか言ってられない感じの時代に。
追記: PCL化 実際やった
WP 7.5 はあきらめて(つまるところ、WP8 実機買うまで自分用ツールの更新あきらめて)Portable Class Library 化してみたり。
- ターゲットは .NET 4.5、.NET for Windows ストア アプリ、Windows Phone 8 の3つ
- View Model 丸ごと全部 PCL 側に入った
- もちろん async/await 使いまくり
- BindableBase (ストア アプリのテンプレに入ってるやつのコピペ。CallerMemberName 属性とか使っちゃってるやつ)も使えた
- Windows.winmd の参照はしてない(pure .NET。WinRT 機能は PCL 側では未使用)
- ターゲットに Phone を入れると WebRequest.GetResponseAsync とかが消えるけども、Bcl.Async を入れれば一応解決
- ただ、PCL → PCL → Phone みたいな2段階参照すると挙動おかしくなる
ほぼ XAML の書き換えだけで移植できるなぁ、これ。
追記2: PCL から WinRT 利用
これもできるみたい。
確かにいろいろとそれを匂わすものはあったけども。
PCL で winmd を参照できたり:
Phone 側、未実装のくせにメソッドだけは持ってるものがあったり:
とりあえずためしにやってみた。
PCL 内に書いたのは↓みたいなコード。
public class Class1
{
// デスクトップから呼ぶと ID がありません的エラー
public static string GetLocalFolderPath()
{
return Windows.Storage.ApplicationData.Current.LocalFolder.Path;
}
// Phone から呼ぶと UnauthorizedException
public static async Task<IEnumerable<PictureDescription>> GetFilesInPicturesLibrary()
{
var files = await Windows.Storage.KnownFolders.PicturesLibrary.GetFilesAsync(
Windows.Storage.Search.CommonFileQuery.OrderBySearchRank, 0, 10).AsTask();
// 以下略。ここから下は、以前、デスクトップ アプリから WinRT を参照したときのと同じ
ただ、いまいちな感じ:
- Windows.winmd は参照できるけども、System.Runtime.WindowsRuntime.dll の参照が消えるみたい
- WinRT の IAsyncInfo とか IAsyncOperation に対する Awaiter や、AsTask メソッドがなくなるので、await できない(自作すれば AsTask は可能)
- 実行してみないと本当に使えるかどうかわからない(実行時例外が出る)メソッドが多々
PCL 内は普通に pure .NET にしとく方が無難な雰囲気。
大切な事は全て.NETから学んだ
下記の文章、「こういうテーマでufcpp.net内のC#ページを更新(今の【雑記】的にやるか、新しいフォルダー掘るかして)したい」というもの。
いつ手を付けるかは未定。実際のところしばらく無理。
表題、誇張ではなく、割と真実。
ソフトウェアに求められる品質水準は非常に高くなっていて、開発者に求められる知識は年々増えています。
単純にプログラミング言語の基礎を覚えるというだけではまるっきり不足で、そこから様々なパターンを覚えて初めて実用化に足る最低水準になります。
パターン。
- こういう場面ではこう書くと解かりやすい
- こう書かないとこんな問題が
- 計算速度優先ならこう、省メモリならこう
等々、いわゆる先人の知恵。
歴史を積み重ね、普通に1からたどるにはあまりにも遠い道のりに至りました。
先人と同じ手順を経ていては、追いつくことで精一杯。その先の新しい世界を目指すことも叶いません。
楽をするひつよがあります。苦労するなら新しい世界に差し掛かってから。
楽。
- 先人は、パターンを教科書的に整理してくれています。
- C♯なんかでは、多くのパターンが言語構文に組み込まれています。
- 解説も豊富です。
整理済みのもの、構文化されたもの、分かりやすい解説のあるものから学びます。
だから、C♯から、.NETから学びます。学びました。これからもまだまだ学べます。
高度さの割に整理されたきれいな言語・フレームワーク。膨大で詳細な解説の数々。
C♯は機能が多くて難しいとも言われます。しかし、それは本当に必要なもので、他の言語であれば、同様の事を実現するためのパターンを覚えて、毎回同様のコードを自分で書かなければならないことです。
書かなければならない。さもなくば
- 時には性能を犠牲にします
- 時には危険を生みます
- 時には後々の運用や修正のコストを増やします
この文章は、そんなC♯や.NETに詰まっている先人の知恵を追うものです。
- 先人に楽して追いつくために
- その先の新しい世界で苦労するために
C♯に頼るというより、C♯から学ぶ。
学んだことは活かされます。不幸にも最新のC♯、あるいは、同様の機能を持った言語を使えない状況でも、C♯から学んだ知識で乗り越えられることは多々あります。
そういう、先人の知恵、楽する手段、学びの糧としてのC♯。
他の言語だと、言語仕様を一通り覚えた後に追加で「パターン本」みたいなものを読んで、覚えて、自由に書けなきゃいけない部分。C#だと、普通にMSDN内で見かける説明文。
以下、なんかこんなの書くかもという自分メモ。
- イベント、オブザーバーパターン、add/remove自作、スレッド安全な作り
- イテレーター
- LINQ
- dynamic、コールサイト、メソッドキャッシ
- 非同期呼び出し
- インターロック同期
- スレッドプール、同期コンテキスト、IO完了ポート
- 仮想テーブル、型のレイアウト情報、ボクシング
- ガベコレ、参照カウント、オブジェクトプール、値型とジェネリック
- unmanaged型(ポインター化可能な型)、参照のピン止め、厳密な型を持った言語のガベコレ/型に緩い言語のガベコレ
- IL、oopなアセンブリ言語、スタック型仮想マシン、共通型システム
- AppDomain、分離、マーシャリング
参考に、C♯ 1.0での実装や、C++とかJavaでの実装とかやってみるかな(大変すぎるのは除いて)。C89でのOOP(というか仮想関数テーブル実装)の話とかも書いたことあるし、そういうの。
ぶっちゃけ、締切なく、小出しで書けて、後から修正効く前提のクオリティで文章書きたくてしょうがない。
VS拡張とか非同期処理のキャンセルとか
ニュースフィード消化も久々。
- Making Instant C# Viable – Visualization
- Roslynを使ったVisual Studio拡張(英語読ななくても動画を見れば大体わかる)
- 要するにリアルタイムprintfデバッグ
- 単体テスト プロジェクトもお試し用のコンソール アプリ プロジェクトも作りやすいVisual Studioでその発想はなかった。けど、場合によっては確かに便利そう。
- Multilingual App Toolkit for developing Windows Store apps using Visual Studio 2012
- Windowsストア アプリの翻訳支援ツール(Visual Studio拡張)
- How do I cancel non-cancelable async operations?
- 元々キャンセルをサポートしていない非同期メソッドに、キャンセル機能(CancelationTokenを受け取る)を付け加える方法
- あわせて: Task-based Asynchronous Pattern – WithTimeout
- 非同期処理にタイムアウトを付ける方法
TypeScript(続)
その後、ちらほら情報追っかけてみていたり。
使ってみるには
とりあえず、Web IDE的なものがあるのでこれで試してみるのがよさそう。
これのために、公開されているTypeScriptのコンパイラーのソースコードはTypeScript自身で作られてるんですねぇ。
で、Visual Studio上で使うには、プラグインのインストールを。
2012が必須ですが、無料で使えるVisual Studio Express for Webでも利用できるので、「Visual Studioは有料だから使えない」とか思っている人もご安心を。
これに付属しているテンプレートが、ASP.NET MVC/C#プロジェクトだけなんですよねぇ。TypeScriptのアイテム テンプレートが出てくるのもC#プロジェクト内のみ。最近はまあいつものことですが、VBな人は置いてきぼり。
TypeScriptのターゲット
「ASP.NET MVCの価値を高めるもの」くらいの位置づけで考えるのがよさそうな気がしてきた。
もちろんまあ、コンパイル結果がただのJavaScriptなんで、TypeScriptで開発したものをコピって配置して、PHPや他のWebフレームワークから使うことはできますが。
現状、Windowsストア アプリの方のJavaScriptプロジェクトからは利用不可(これもよそからコピってくる方法で使えはしますが)。まあ、Windowsストア アプリでそういう開発がしたければ、普通にC#/XAML使えって話ですが。
そして、まあ、JavaScriptの性能問題を解決できるようなものでもなく、あくまでJavaScriptの延命処置。
ベターJavaScriptでしかなく、JavaScript(TypeScript)で閉じた世界(.NETやWinRTがやってるような他の言語との相互運用や共通型システムがあるわけじゃないし、Roslynみたいなホワイトボックスなコンパイラーはない)。
型情報の追加
TypeScriptは、まあ、名前通りなんですけども、JavaScriptに型情報を追加する(VS上でのリアルタイム型チェックや補完の恩恵受ける)ための拡張といった感じのもの。
なので、既存のJavaScriptコードをそのまま持ってきた上で、追加で型情報を入れるための機能がかなりいい具合。
Structural Typing
継承不要で、同じ名前のメンバーさえ持っていればインターフェイスに代入できるようになるという、動的型システムに非常にマッチした強い型付けの仕組み。
interface Point
{
x: number;
y: number;
}function Length2(p: Point)
{
return p.x * p.x + p.y * p.y;
}var x = Length2({x: 10, y:20});
関数型言語の類でよく見るし、Go言語なんかでも使われてる型システム。C#にも微妙に欲しいんですよねぇ。静的な型の範囲ではそんなに必要ないんですけども、dynamic使って外部システムと連携したりすると。昔からずっと言ってるんですけども、interface for dynamic。C++ 11に入り損ねたConceptsみたいなもの。
Ambients
要は、宣言のみのクラス・メソッド・変数定義ファイルを作れる機能。
既存のJavaScriptコードをそのまま持ってくると、当然型情報が欠けけてるわけですが、そっちに手を入れず、追加で .d.ts という拡張子のファイルで宣言のみを書いて、型情報を追加できる。
例えば、JavaScript標準の関数に型情報を追加するために、lib.d.tsっていうファイルを提供していて、一部抜粋すると以下のような内容になっています。
declare var NaN: number;
declare var Infinity: number;
declare function eval(x: string): any;
declare function parseInt(s: string, radix?: number): number;
declare function parseFloat(string: string): number;
declareキーワードを付けると、宣言のみの変数、関数を作れます。
ディスカッション
公式サイトのフォーラムにて。
Q. ジェネリックはないの?
計画にはある。1.0までには入れると、0.8の仕様書に明記あり。
JavaScriptへの変換で実現されてる以上、実装方法は「型消去」。
Q. letないの?
要するに、immutableな変数定義。
「TypeScript上で型チェックするだけで、JavaScriptへの変換結果はvarと同じでいいんじゃないの?簡単じゃないの?」と思うかもしれないんですが、そうでもないらしい。
というのも、クロージャーへの取り込みルールとかが変わるので、そこがそこそこ面倒みたい。
ECMAScript 6にもあるし、入れる計画はある。
Q. async/awaitないの?
C# 5.0/VB 11のコード生成結果を調べたことがある人ならわかるとおり、async/awaitはかなり大がかりなコード生成を行っています。
もしTypeScriptにasync/awaitを入れるなら、生成結果のJavaScriptがかなり恐ろしいことになるはず。実装コストや、実行効率的に悩ましいところ。
もちろん、それ以上に便利な機能なので要望かなり多く、実装の検討には入ってもらえそう。
Q. C言語スタイルの「T x」形式の型宣言が欲しかった
C言語スタイルの型宣言は、型の省略が可能な場面になると結構破たんする。
TypeScriptは、JavaScriptがベースで、型の省略が当たり前なので、x: T の方がきれい。
Q. C#のXmlドキュメントみたいな機能ないの?
今、JSDoc形式を調べてるところ。
Q. デリゲートはないの?
インターフェイスを使ってデリゲートもどきを作れるみたい。
interface FooDelegate {
(a: string, b: number): void;
}
C++の () operator的というか。
まあ、関数型の型指定も => を使ってできるので、これを使えばデリゲート型みたいなのを作る必要性あまり感じませんが。
function Foo(callback: (a:string, b:number) => void)
Q. C#のインターフェイスからTypeScriptのインターフェイス生成できないかな?
Roslyn使って。
TypeScript
マイクロソフトも better JavaScript、かつ、JavaScript に変換して使う言語を作ってきたようで。
- 日本語ニュース記事: Microsoft、JavaScript系の新言語、TypeScriptのデベロッパー・プレビュー版を発表
- 公式サイト: http://www.typescriptlang.org/
- MSDN ブログでの告知: TypeScript: JavaScript Development at Application Scale
- Miguel de Icaza(GNOMEとかMonoの創始者)の感想: TypeScript: First Impressions
「JavaScript を、最小限の変更で、ツール連携(静的チェックやコード補完)しやすくする」という観点でみて、結構よくできてる。
少し前に、Anders Hejlsberg が JavaScript がらみで何かやってるというような話が出ていましたが、これのことだったんですねぇ。
いいと思う点
- ほぼ JavaScript
- スーパーセット(型指定が増える程度で、式とかはそのままで実行可能)
- 追加分も最小限
- 型付けを持つことで、実行しなくても確認できるエラーが多い & Visual Studio による補完が協力
- クラス、インターフェイス、モジュールをサポート
- ラムダ式(TypeScript 的には「arrow function expression」。x => x * x みたいな匿名関数)もサポート
- JavaScript への変換で実現
- あくまで、標準に沿ったブラウザーなら何でも実行可能
- 「IE だけ特別処理」みたいなこともしてない
- コンパイラーがオープンソース
下手に新言語を作らないという、作成コストや移行コストの最小化路線。
あと、最近のマイクロソフトのオープンソース路線、かなりいい感じですね。いっそ、Roslyn(というか、C#で書かれたC#コンパイラー)とかもオープンソースになってくれたりしないものか。
いまいちと思う点
- JavaScript な人にとっては Visual Studio でなく、Eclipse プラグインとかもあった方がよかったのでは
- JavaScript への変換時点で型情報は消える
- (標準ブラウザーでの実行面を考えるとやむを得ないやり方)
- 型情報があれば本来できるはずな実行最適化はできない
- 結局 JavaScript
- 地盤が緩いものを何とかごまかして支えてるだけという状態からは変わってない
- かなりの部分、ECMAScript 6.0
- 標準化が滞りなく進んでいたら必要のなかった作業を、わざわざ各社ばらばらにやってるだけ
- 「標準化をせかす」というのが最大の目的だったりするのかも