Quantcast
Channel: ++C++; // 未確認飛行 C ブログ
Viewing all 483 articles
Browse latest View live

ピックアップRoslyn 12/18

$
0
0

CoreCLR側との兼ね合い

DNX向けに、ASP.NETチームの方が実装しちゃってるけども、Roslyn側の協力がほしそう・Roslyn側で取り組んでほしそうな話が2件。

ICompileModule

https://github.com/dotnet/roslyn/issues/5561#issuecomment-164688325

DNX側で、ICompileModuleインターフェイスを実装しておけばコンパイルの途中で独自処理を挟めるという実装があったりします。そのタイミングで、Roslynコンパイラーからの内部情報をもらいたいという要望が出ていて、「それはRoslyn側の仕事だ」と誘導されてきたのがこれ。確かに、今、C#でもCode Injector(コンパイル時に処理を挟む仕組み)の検討してるところだし、統合されてほしいところ。

async Main

Async Main [Speclet] #7476

Mainメソッド(プログラムのエントリー ポイント)に非同期メソッドを認めてほしいという話。

これ、DNXではいったん独自に実装したものの、既存の.NET Frameworkコードに対して破壊的変更になるというおしかりが多く、RC版で撤廃されたところなんですよね。

それが改めてRoslyn側で提案されたという。void Mainがあったらそっちを優先するみたいなルール設ければ破壊的変更にならないはずだし、改めて取り組んでもらいたいところ。

まあ、Roslyn側でも何度かこの話題出てたはず。その時問題になってたのは同期コンテキストをどうするか。といっても、非同期Main以前からの問題で、GUIだと同時実行制御いらない(awaitしたときにUIスレッドに戻ってきて、単一スレッド実行が保証される)のに、コンソール アプリだとそういう仕組みが働かないのでlockとか書けないとまずくなるプログラムが出てくるっていう問題。

インライン アセンブラー

Roslyn側に提案が出ているわけじゃないんですが。corefxlab上のコードでえげつないものを見てしまい。

PtrUtils.cs

ILSub属性内に文字列でILアセンブリ コードを書いて、それをビルド後処理でILコード刺し込みしてるみたい。何かいいツールがあるのかと思ったら、その処理自体自作

こんな黒魔術やってる理由は、ガベコレがオブジェクトを追える状態のままポインター操作したいかららしい。それは要件からして大変黒魔術的。パフォーマンス改善のためなので黒魔術になりがちなのはしょうがないんですが、書いてる本人からしてコメントに「なんとか動く」、「きたないトリック」、「Very Bad Things」とか言っている状態。

これ見てると、C#にインラインILアセンブラーを追加してほしいような、追加したいと思うような場面がそもそも魔術的過ぎるような。

プロトタイプとか仕様とか

いくつか、プロトタイプ実装が動きだしてたり、仕様が固まり始めてたりしてるみたい。

  • https://github.com/dotnet/roslyn/issues/7445 非null参照型、プロトタイプ実装開始
  • https://github.com/dotnet/roslyn/issues/357#issuecomment-162603202 covariant return types、詳細詰めれたっぽい

めとべや東京 #10 にて登壇

$
0
0

めとべや東京 #10 にて登壇してきました。

まあ実は、元々別の勉強会での発表になる予定だった資料なんですが。どうしても都合がつかずに、資料作りかけの状態で未発表だったもの。

メトロっぽくない感じでしたが、まあ、この苦労を最初に負ったのはWindows Phone Silverlightであったり、Windowsストア アプリであったり。そこからUniversal Windows Platformや.NET Coreに進化し、今ようやく問題解消の光明(というか長い長い投資の回収フェーズ)が見えてきたという。

Continuum

ちなみに、今日の登壇、Continuum使ってのプレゼンでした。プレゼンの内容よりもむしろそっちが本題みたいな。

たぶん、最初にContinuum見せびらかすのやらずに登壇してたら、僕がLumia 950 XLでプレゼンしてるということに気づかなかった人もいるくらいではないかと。割ともう、勉強会にはノートPC持っていかなくてもいいかなぁ。Visual Studioを使ったデモとかは厳しいでしょうけど、それも、回線速度次第ではAzure VM上へのリモート デスクトップ接続でいいでしょうし。

ちなみに、Lumia 950でContinuumやるのに専用のドックとかは必要なくて、単にUSB-CからHDMIへの変換ケーブルだけあれば十分です。MacBookで使えるやつ。

Windows 10 Mobile人柱中

$
0
0

最近、「Surface Book買わない人」として有名なわけですが。だって、ノートPCとか重たくて持てない。スマホでいいよ、スマホで。

ということで、今週中、「リビングでWindows 10 Mobileを使って作業しよう強化週間を実施しております。

Continuum

最大の動機は、手元にContinuum対応端末があることです。 要するに、Lumia 950 XLを買ったから。

Continuumは、Windows 10 Mobile最大の売りになるかもしれない機能で、スマホとPCで同じアプリを同じように使える機能。普段スマホ上ではスマホ サイズに起動しますが、ディスプレイにつなぐとPCサイズなアプリとしてちゃんと起動するというもの。

Continuum対応のWindows 10 Mobile機をディスプレイにつなぐと、ディスプレイには見慣れたWindows 10 PCのような画面が現れます。スマホ側はタッチパッドみたいな状態になって、ディスプレイ側に出ているアプリを操作(モード切り替えできて、スマホ側は別のアプリを起動して使うことも可能)。キーボードやマウス(Bluetoothや、USBハブ越しに接続可能)もつないで、かなりPCに近い操作ができます。

Lumia 950 XLをディスプレイにつないで見たところ ↑Lumia 950 XLをディスプレイにつないで見たところ。画面に出ているPowerPointはLumia上で動いているもの。

Lumia 950 XLにBluetoothキーボードを接続 ↑Lumia 950 XLにBluetoothキーボードを接続。マウスも行けます。これで、かなりPC的に操作可能。

Continuum (連続体)という名前通り、スマホ、タブレットとPCを連続的につなぐものです。

ただしUWPに限る - とりあえずOfficeは対応済み

ただし、Continuumで使えるアプリには制限があって、今のところUWPアプリのみ対応。 さんざん言われているように、「Windows Phoneはアプリが少ないから困る」問題があるわけです。

まあ、とりあえず、OfficeはUWP化されました。これが結構大きくて、原稿書きや表計算であれば結構使える状態です。まあ、まだまだ「時々フリーズ」みたいな不具合は出ますが、機能的には「人柱はできるレベル」になったかなぁと個人的に感じています。ちなみに、書いてるドキュメントの自動保存とかはずいぶん発達していて、「フリーズして作業紛失」みたいなので困ったことは、最近ではめっきりなくなっています。

連続的につなぐもの

「スマホでいいよ、スマホで」って、割かし今の日本を指す的確な言葉だと思うんですよね。ちょっと前に、「日本の若年層、PC普及率が先進国で最低レベル」とかいう話題も出たわけですが。これ見てみんな思ったであろうことは「だってスマホで十分だから」でしょう。

これに関して個人的な意見としては、「日本はおかしい」とか「日本は遅れてる」じゃなくて、むしろ「日本は先を行ってる」だと思うんですよね。理由は以下の2点。

そこで問題になるのが、スマホ ネイティブだからPC使えない問題。 スマホではコンテンツ消費はできるけど、コンテンツ生産は難しい。生産者が育たないってやつ。 割かしわかりやすいデジタル デバイドの1つです(もう今、スマホはまず必需品なので持ってるとして、スマホ + PCとか買える家庭だけが有利)。

「Continuumがつなぐのはこの溝ではないか」というのが、自分がContinuumに一番期待しているところです。 「スマホだとコンテンツ生産者が育たないからPCを買いなさい」なんてのはマリー アントワネット的発想の一種。 そうじゃなくて、もう、スマホ側伸ばす方が現実的な段階に来たのかなと思います。

まあ、Bookも買えばいいじゃない

さて、まあ、別に「マリー アントワネット側」な発想してもいいんですけど。買いたいだって?買えばいいじゃない。

特に買いたいと思わない真の理由は、自分がひきこもりだからなわけですが。つまるところ、PCの前にしかいない。外出と書いて「トイレ行き」を指す。まれに遠出(※家の外に出ること)する時くらいはスマホで十分なわけです。一刻も早くおうちに帰りたい。

実際、自分が家・職場の外にいる時間のうち、多少なりともノートPCがほしいなと思うような場面は勉強会くらいなわけです。 普段、例えば、電車の中で文章打ちみたいなことも結構しますが、その用途ももう長らくスマホでやっています(というか、15年以上、ガラケー時代からケータイで文章打ってたり)。 勉強会も、視聴者側参加の場合はセッション聞いた感想やら補足やらをtwitterに垂れ流すくらいなので、それもスマホで十分です。 これまでの唯一の問題だった登壇側も、Continuumを使ってクリアできることが先週確認できました

家庭内mobility

しかし、「家の中ですらひきこもり」というのがまた問題なわけです。ぶっちゃけていうと家族との時間すらなくなる。旦那/お父さんが書斎にこもってPC作業しててみなさいよ、まず「邪魔しちゃ悪い」感じになって、家族と顔合わせない。 なので、よっぽど切羽詰まった作業でもしてない限り、リビングでだらだらと作業したいなと思うわけです。

という背景の中、メイン機のデスクトップPC、やむなく遠出(※家から出ること)するときのためのスマホに加えて、近場に出かける(※PC前から動くこと。家の中含む)という第3の要件が発生。家庭内でのmobilityが必要。 この微妙な中間要件用に3台目を持てというのか…っていう話になるわけです。できればここもスマホに集約したい。

ちなみにまあ、職場に放置気味なSurface 3も持ってたりするので、実はそれを家に持って帰って来ればいい話なんですが。それはそれで、めったに使わないものを放置しておくスペースってのが必要で結構ストレスがでかいというのが、これまでの経験的に率直な感想。普段使いのものをそのまま使いたい。そして今は、普段使いのもの = スマホ。

始めてみよう、Windows 10 Mobile作業

と言うわけで、家庭内Mobilityの確保のためにWindows 10 Mobile作業の人柱をやってみようということにしました。

Continuum の使い方

とりあえずContinuumの使い方から。

対応機種

対応機種は、今のところ輸入端末のみ、日本ではNuAns NEOが対応するかも(※ハードウェア的にWindowsに正式サポートされるかどうかきわどいラインらしいものの)ということで期待されています。来年には他にも出そろってくれるのかなぁ。

比較としてSurfaceで考えると、そんなに評価の高くない初代Surface (2012年10月)から、結構売れだしたSurface 3 (2015年5月)までに2年半とかかかってるので、 これから1・2年は人柱な感じかもしれませんが。

追加で必要なもの

Continuumの記事を見るに、なんかドックみたいなものが写真に移りこんでるので、何か専用のハードウェアが追加で要るのかと勘違いしがちですが、別に必須じゃありません。

あのドックは、

  • 給電
  • USBハブ
  • HDMI出力

の複合品。電池動作で頑張るなら給電は要らないし、キーボード・マウスをBluetoothで行くならUSBハブも特に不要。問題は、映像の出力くらいですね。ちなみに、Lumia 950はMiracast使えるみたいなので、ディスプレイ側が対応していればHDMI出力も要らないはずです。

ということで、以下のいずれかがあればContinuumを使えます。

Miracast対応ディスプレイに関しては、いまどきは多くのテレビが対応してるみたいですね。試しに電気屋で「ワイヤレス ディスプレイに接続する」設定画面開いてみたら、家電フロアのテレビが大量に応答してました。

実際の導入状況

とりあえず勉強会登壇用途のためにUSB-C から HDMI への変換ケーブルを買いました。これは結構満足。

家庭内Mobilityに関しては、リビングにディスプレイを置くのかという問題をどう回避しようかで悩み中。 リビングなので、Miracast対応テレビを置くという手もあるんですが。前提が「家族と」なので、テレビは家族に取られてるもんだと思った方がよさそう。追加でMiracast対応ディスプレイを買うのは、「たまにしか使わないものをどこに置いておくのか」問題に抵触するのでこれもまた微妙。

結局、さしあたって、Bluetoothキーボードだけつないで、スマホ画面中で作業という苦行を試してみています。散々Continuumの宣伝しておいて、実はContinuum使ってないという。まあ、Windows 10 MobileでOfficeがまともになったので…

ディスプレイをどうしよう問題も継続的に悩むとして、先にキーボードとかスマホ スタンドとかをどうしようという辺りを検討という感じです。

  • Universal Foldable Keyboard: 昨日買ってみた。ソファー上とか、安定しない場所で使うには微妙かなぁという感想。折れ目が固定されないんで常にふにふに。折り畳みは結構すっきりしてるんで、これは勉強会に持っていく用途の方がいいかも。
  • KEYS-TO-GO: Foldable Keyboardを買いに行った時にいろいろ触って試してみて、一番いいなと思ったのはむしろこれ。実際にLumiaにつないで使ってないので何とも言えないものの。
  • Wedge Mobile Keyboard: そういや昔試しに買ってみて眠ってるWedge Keyboardが家にある… 家庭内Mobilityくらいの近距離用途なら、これくらいのサイズのものが一番いいかも。スマホ スタンドになるカバーも付いてるし。
  • PCスタンド: 昨日、床作業・ソファー作業が結構きつかったんで買うかどうか迷ってるのがこの手のPCスタンド。邪魔かなぁ… 普段の置き場に困るよなぁ…

まとめ

デスクトップ前にしかいないのにノートPCとか要るわけないじゃない。スマホでいいよ、スマホで。

PCが売れない、スマホが原因でPCスキルが上がらないことが問題視されている今、スマホでPC並の作業をできるようになることに期待しています。

そういう視点で、Windows 10 Mobile作業の人柱始めました。まだそろえる道具どうするか検討中ですが、Continuumには引き続き期待。

Commonly Rejected Changes

$
0
0

twitterで見かけた話。きっかけはSwiftのものなんですが、「Commonly Rejected Changes」、つまり、「頻繁にリジェクトされる変更の提案」集がまとめられてるみたいです。これを見た感想は「ああ、あるある、C#でもよくある」だったので、それをネタにしてみようかと。

{} をやめて、Python風のインデント構文がほしい

これ、SwiftやC#に限らずありとあらゆるプログラミング言語で発生すると思うんですが、必ず出てくるんですよね、インデントでブロックを切る構文を求めてくる人。SwiftにしろC#にしろ、基本方針として「空白文字を除外しても意味が変わらない」を採用している言語に対してそういう要求をされましても…

まあ、Swiftは「空白を抜いたら意味が変わる」構文あるんですけどね。?:?の前にスペースを入れないと、型名??と区別がつかないそうで。

それを言い出すと、C系言語共通で、a+++bの解釈は空白の入れ方によって変わってしまうわけですが。

セミコロンなくして

同上。

「空白文字を除外しても意味が変わらない」方針と相性悪いんですよねぇ、セミコロンlessプログラム。 改行のあるなしで実行結果が変わることがあるとか、割かし悪夢を生みます。

逆に、「改行区切り」の代表格、Visual Basicなんかは、改行を挟めない(挟めなかった)ことでいろいろ苦労していますし。

記号が分かりづらいから止めてほしい

2件ほど。

  • &&|| の代わりに and or とかにしてほしい
  • 条件演算子 ? : はわかりにくいからやめてほしい

いずれも、本質は「記号が分かりづらい」だと思います。

これはわからなくはないもの。「式」=「演算子」=「記号」ってのは、C言語の悪い癖な感じもします。確かに初見の人には優しくなく、googlabilityも悪い。

でも、そのために予約語(= 変数名などに使えない)を増やすの?とか、C言語をすでに知ってる人の数が多いのでわざわざ変えるメリットも低いとかあり。

if/elseとswitchを式にしてほしい

if/elseは、前節の「? : が記号だからわかりづらい」問題と同義でしょう。「if/else相当の式」は? : でできる話なので。

switchは、C#だと7で式バージョンのswitchが入る方向で議論進んでいます。

C#の場合は、これまで、if/elseやループに相当する式は書けたもののswitchはなかったので。

ステートメント
if/else '? : '
foreach LINQ
switch switch (C# 7向け提案)

これまではswitchの利用頻度がそこまで高くなかったのでそんなに欲しいとも思わなかったものの、C# 7では別途パターン マッチングで使えるようにswitchステートメントを拡張する予定なので。そうすると「switch式」もほしくなるだろいうということで、一緒に提案されています。

ただ、こうなるとますます「? : が記号だからわかりづらい」というのが分からなくもない話に。 switchは、ステートメントでも式でもswitchキーワードを使います(式はもしかしたらmatchキーワードになる可能性もあるもの、いずれにしても記号ではなくて英単語)。 なので、if/elseの式バージョンも、if/elseっていう英単語の方が分かりやすかったりしないかなぁとは少し思います。

まあ、今更の変更は無理ですが。

Swiftを使ってSwiftコンパイラーを書き直して

C#も10年くらい言われ続けました。C#の場合はそれがRoslynなわけですが、これがどれだけ大変だったか。

実際のところ、「既存のプログラムと互換性を保ったものを、別の言語に移植」というのはかなり不毛な作業です。よっぽど強い動機がなければできない。C#の場合は以下のような動機がありました

  • さすがにC++製コンパイラーだと機能追加が苦しくなってきた
  • Visual Studioとの連携(コード補完、静的コード解析、リファクタリング)の高機能化が難しかった

が、これも「10年越しの実現」です。「そろそろ苦しい」が「移植の不毛さ」を上回るのにそれくらいの歳月がかかっています。

また、Roslynの完成は相当待たされました。理由は、以下のようなものです。

  • 他部署からの要望(C#の場合はWindows 8関連、つまり、Windows Runtime APIと非同期処理への対応)に時間を取られて、なかなか「単なる移植」には人員を割けなかった
  • 「単なる移植」で数年、言語の進化を停滞させるのもつらい
  • 実はバグだった挙動も含め、元のコンパイラーの挙動を変えると、世の中に出回っているコードを壊すので、そこの互換性確保が結構つらい

こういうハードルがあって、結局、「C#コンパイラーのC#化」に取り掛かってから、リリースまでに5・6年はかかっています。C#自体の発表から数えると、15年の歳月をかけてやっと「C#化」されました。

クロージャの構文を変えてほしい

これは、C#だとあんまり言われないんですよね。みんな、ラムダ式におおむね満足しているようで。

多少の提案はあったりはするんですが。

シングル クォートの文字リテラルがほしい

Swiftって文字リテラルと文字列リテラルの区別ないんですね…

これはでもなかなか難しい問題でして。特に、1文字が何バイトになるか全くわからない現在となっては。

マイクロソフト内部でC#を作り始めた当時(だいたい1998年頃)は、Unicode出始めの時期、つまり、まだ16ビットですべての文字を表せるという幻想があった頃です。なので、char型は16ビットだし、stringはそれの配列に皮を被せたような構造。

ですが、今はどうかというと。サロゲート ペアがあり、結合文字があり、異体字セレクターがあり。最近だと、絵文字がなかなか来てます。肌色(異体字)セレクターと結合の組み合わせで、「色白男性と色黒女性の家族」みたいに、1文字で表示されるけどもデータ上は何バイトも使う文字すらあります。

結局、世の中の主流派UTF8、つまり、可変バイトの文字列符号化でして。Webでレガシーとの互換が必要ないものだと、ほとんどのテキストがUTF8で流れてるんじゃないですかね。となると、C#でパフォーマンス的にネックになりがちなのが、UTF8からstringへの変換処理だったりします。その結果、今、stringとは別に、System.Text.Utf8.Utf8Stringなんていうクラスを別途実装中だったりします。この場合、16ビットなcharは大して意味をなさなかったり。

continueキーワードを、スクリプト言語でみられる他のキーワードに置き換えてほしい

これもC#だとあんまり言われないですね。

まあこれ、「自分が慣れた言語に近づいてほしい」欲なんですかねぇ。C#の場合は名前にCという文字がはいってるのもあって、「C系文化」から外れようという提案は少な目なんですが。Swiftは結構「脱C」しているのでこういうこと言われてしまうのかも。

switch 中で、default の代わりに case _ を使いたい

C#では、C# 7でパターン マッチングが入って、その仕様の中に case * で任意のパターンにマッチというのを作れるので、確かにdefaultとの住み分けはどうなるんだろうって思います。まあでも、C系言語に脈々と受け継がれてきたdefaultの使い方を変えるだけの価値があるかと言われると。

「コンピュータープログラミング入門以前」電子書籍キャンペーン

$
0
0

達人出版会×マイナビ出版で年末・年始電子書籍セールをやっているそうです。

自著の「コンピュータープログラミング入門以前」も対象なので宣伝。

「コンピュータープログラミング入門以前」は結構前に書いた本なんですが、今は転載の許可ももらって、ufcpp.netの「コンピュータの基礎知識」に低レイヤーの話を移植していたりはします。また、上の方のレイヤーの話も「C#によるプログラミング入門」のあたりに部分部分反映させてたりはします。ほぼ同じ内容なんですが、広告なしで読みたいとか、出版社の編集が通ったきれいなレイアウトで読みたいとか、お布施したいとかあれば、ぜひ電子書籍版をお買い求めください。

ちなみに、「入門以前」ってタイトルだけど入門にはちょっとレベル高すぎないか?などというフィードバックを大変多くいただいたりしていますが、そもそもその戦犯は先達の「Cプログラミング入門以前」だったりします。こちらが「入門以前」というタイトルで、結構幅広い話を書いているので、それを倣って、「コンピュータープログラミング入門以前」のタイトルが決定しました。こちらの「Cプログラミング入門以前」もキャンペーン対象に並んでいるのでこの際、併せていかがでしょうか。

ピックアップRoslyn 1/9: structural typing

$
0
0

C#にstructural typing(構造的型付け)を入れようという案。

まあ、「何人かでちょっとディスカッションしたよ」というくらいの段階みたい。やりたいことの説明や、構文の案(3案ほど)が出ている程度(実装方法に関する言及あまりなし)。

以下、structural typingがどういうものなのかについて簡単に説明。

Goのインターフェイスがそうなんですが、明示的な実装を必要とせず、「同じシグネチャ(名前+引数一致)さえ持っていればなんでもOK」という方針で代入可能な型システムをstructural typingと言います。

Javaとか.NETのインターフェイスやクラスの継承・実装、C++のクラス継承なんかは、以下のように、明示的な参照・実装が必要になります。こういうのはnominative(指名的、任命的)な型付けといいます。

.NETのインターフェイス(nominative typing)

一方で、Goのインターフェイスは、(C#で提案されている案の1つを使って類似機能を書くと)以下のように、シグネチャだけ見て暗黙的に「実装されている」ことにしてくれます(これが、structural)。

structural typing

もちろん良し悪しあって、以下のような感じ

  1. nominativeな方が若干実行性能がいい
  2. ただ、structuralの方はほんの小さなコストで、結構大きな自由度が手に入る
  3. structuralの方は、実装クラス側が知らず知らずのうちに合わない構造に修正される可能性がある

3番目の「知らず知らずのうちに修正」が怖いので、Javaとか.NETとかみたいな動的リンクが基本のプログラミング言語ではstructuralのデメリットが大きいんですが。Goの場合は静的リンクだからインターフェイスをstructuralにできたというのもあるはず。

とはいえ、別にどっちか片方だけでないといけないということもないわけです。C#では、普通のインターフェイスはnominativeだけど、追加でstructuralな何かを加えて使い分けたってかまわないはず。「知らず知らずのうちに修正」問題をどう対処するかだけ決まればC#でもstructural typingの便利さを享受できるはずです。

ピックアップRoslyn 2/6

$
0
0

コンストラクター引数を元にオブジェクトの分解(deconstruction)

Proposal: Positional deconstruction based on existing constructors and properties #8415

パターン マッチングで、現在提案されている範囲では、is 演算子みたいな特殊なメソッドを1個追加してやらないと、o is Person("Alan", var last) みたいな感じのマッチングができません。

これだと、今後追加する型(特にレコード型)に対してなら使えるけども、既存の型には全く使えなくて困る。一方で、現状でも、以下のコードみたいに、コンストラクター引数とプロパティに1対1の関係があるようなクラスを書く人は多いわけで、この規約ベースでオブジェクトの分解をできないかという提案。

public class Person
{
  public Person(string firstName, string lastName) 
  { 
    FirstName = firstName; 
    LastName = lastName; 
  }
  public string FirstName { get; }
  public string LastName { get; }
}

確か自分もこのパターンでクラスを書いていることが多いんで、にこの機能が入れば、それらを1個1個レコード型に置き換えたりしなくてもパターン マッチングが使えて大変便利。

でも、引数のfirstNameとプロパティのFirstNameの対応関係を規約ベースでやるのは、C#の文化(規約を嫌う、識別子は大文字小文字を区別する)的には合わないんで悩ましい感じ。ついてるコメントも賛否両論です。

Swift 2.0

Swift 2.0でdeferとguardが入ったわけですが、先月、それはC#には適するかどうか、議論用のissueページが立ちました。

ついてるコメントからすると、賛否は半々くらいか、ちょっと否定が多いくらいかなぁ。個人的な予想では、採用されない気がする。

defer

try { 処理 } finally { 後始末 } の代わりに defer { 後始末 } 処理 と書くような構文。

    {
        SomeType thing = Whatever...;
        defer {
            thing.Free();
        }
        // some code code using thing
    }

メリットは以下のような感じ。

  • using 相当の機能を、IDisposable 実装していなくてもできる
  • try-finally と比べて、「処理」の部分がネスト深くならない
  • try句内と、finally句内の両方で使いたい変数をわざわざその外側で宣言する必要がない

ただ、以下のような問題も。

  • defer が複数並んでるとき、その実行順はどうすべき?
  • try-finally でできることに対してわざわざ新構文増やすの?
  • 1回り外側のブロックに対して影響を与えるような構文ってなかなか理解されにくい

guard

if (絶対満たすべき条件) ; else throw 例外; みたいなよくあるパターンに対して使う構文。絶対満たすべき条件だし、満たしてなかったら必ず例外を投げる(そこから先を絶対に実行しない)ことを保証するために、if じゃなくて guard を使おうというもの。

まあ、そういうものがほしいこともあるというのはわかるものの、コントラクトと被ってるし、そもそもguardの必要性を減らせそう(コンパイル時にチェック可能で、実行時に例外投げる必要がない)な構文もこれから増えるだろうし。

.NET Coreへの移植

$
0
0

twitterで流れてきてて、気になったやつ。

内容的には、

  • フィードバック募集中なのでお願いします
  • .NET Coreは今、ASP.NET、UWP、コンソール アプリに使えるけども、.NET Frameworkからの移植のモチベーションはそれぞれ何か
  • .NET Framework と .NET Coreの関係・差分
  • 意図して.NET Coreには取り込まなかったものがちらほらあるから注意
  • .NET Core化するかどうか、単純に時間的な不足で検討してないものもちらほら
    • 特にフィードバックほしいのはここ。ほしいかどうか、優先度付けしたい
  • 移植にあたってのコツ

みたいなの。

以下、さらっと概要。

何を移植するか

ASP.NET

移植する理由:

  • .NET Coreならクロスプラットフォーム。MacやLinuxで動く
  • マシン全体に対するインストールじゃないんで、デプロイが楽(管理者権限とかも不要でバージョン変えれる)

移植するとよい候補:

  • MVC/Web API使ったものなら移植しやすいのでお勧め

あまり移植に適してないもの:

  • WebFormsは .NET Coreに移植してないので、WebFormsを使っているものは以降大変。ほぼ再実装に
    • もちろん、そろそろWebForms自体をMVCとかに置き換えたいと思っているなら話は別

UWP

移植する理由:

  • (.NET Coreへの移植というか、既存GUIフレームワークからUWPへのという意味で)PC、tablet、phablet、phone、Xbox、IoTデバイスと、広範囲のデバイスで統一的なアプリ開発ができる

移植するとよい候補:

  • Windows 8/Windows Phone 8.1アプリは最初から.NET Core
    • .NET Coreの前身というか、いずれ.NET Coreが出ることを前提として設計されたというか、ほぼ Windows 8アプリ = .NET Core + Windows UIフレームワーク
  • Silverlightアプリも、開発モデルはUWPとかなり近い

あまり移植に適してないもの:

  • Win32なデスクトップ機能をフルに使ったWindows ForsmアプリやWPFアプリは
    • ただし、WPFアプリのXAMLを使った開発スタイルはUWPとかなり近いので多少楽

コンソール アプリ

移植する理由:

  • これも、クロスプラットフォーム対応
  • .NET Native (事前に必要な部分だけネイティブ化した単一実行ファイルを作ってしまう機能)を使いたい場合

移植するとよい候補/あまり移植に適してないもの:

  • 単純に依存しているライブラリが.NET Coreに対応してるかどうか次第
    • ASP.NETやUWPと比べるとハードル低いはず
  • 例えばCOMとか使いまくったWindowsとかOfficeの自動化アプリは移植できないだろうし移植の意味もなさそう

.NET Coreと.NET Framework

.NET Coreは、ある程度.NET Frameworkのサブセットになるように作られてるというか、Visual Studio 2015時点くらいまではそうなるようにある程度頑張ってたはず。でも、ずっとそうなるように維持するつもりはないみたい。現状でも.NET Core側だけにある機能がちらほらあるし、今後はまず.NET Core向けに機能実装されてくことになるはずだし、それが.NET Framework側にバックポーティングされる保証はない。

といっても、かなりの部分は.NET Core向けと.NET Framework (4以降)向けでコード共有できるはず。

差が生じる理由は大まかにいうと以下の3点に由来:

  1. NuGetベース
    • .NET Frameworkはシステム全体に対するインストールが必要
    • .NET CoreはNuGetパッケージ マネージャーを使ってモジュールごとにバージョン管理可能
    • なので、大体において、.NET Coreの方が新機能を早く使える
  2. きれいにレイヤー分け
    • .NET Frameworkではレイヤー分かれず低層から高層まで丸ごと含んでたようなライブラリが結構ある
    • .NET Coreではその辺りを整理して分割したものがある
  3. 問題ある技術の除外
    • .NET Framework 15年の歴史から、問題がはっきりしてて、新規実装の際には取り入れたくないものがある

変化の激しいもの: リフレクション

リフレクションは結構APIが変わっていて困るもの代表で。理由は:

  • レイヤー分けの問題: objectType に依存することで、System.Reflection過剰に参照されかねない
    • Typeには型識別(型の一致判定とか、型の名前を取得したりとか)だけ残す
    • 動的実行や動的コード生成に必要な情報はTypeInfoに分離
  • そもそもリフレクション非推奨
    • .NET Native (事前ネイティブ化)とは相性悪すぎる

.NET Coreには実装しないもの

AppDomain

理由: .NET Coreみたいな層でサポートするにはコストが高すぎる。.NET Nativeでは使えない

代替技術: コード分離(isolation)はプロセスとかコンテナーとかの技術使ってほしい。動的なDLL読み込みのためにはAssemblyLoadContextっていう新しいクラスがある

リモーティング

理由: RPC(remote procedure call)自体がいまいちと認識されてる。AppDomain間の通信みたいなものなので、非常に高コスト。

代替技術: プロセス間通信だったらpipeとかmemory mapped fileとかを使うべきだし、マシン間通信だったらHTTPとか使ったネットワーク ベースの技術使うべき。

バイナリ シリアライズ

理由: privateなデータまでアクセスしちゃうし、互換性を取る上で重荷でしかない。

代替技術: 要件によって最適なシリアライザーは変わるだろうけど、それを要件に合わせて選んでほしい。候補としては、data contract serializerXMLシリアライザーJSON.NETprotobuf-netなど

サンドボックス化

理由: これも.NET Coreみたいな層でサポートするにはコストが高すぎる。正しくサンドボックス化するのはかなり難しくて、信頼も置けない。

代替技術: OSレベルでのセキュリティ境界を使ってほしい。

移植も考えているもの

現状の.NET Coreにないものはもっといろいろあるものの、移植しないと決まったわけじゃなくて、単純に時間が足りないものもある。これに関しては、移植の必要性がどのくらいあるか、特にフィードバックがほしいみたい。

  • System.Data
  • System.DirectoryServices
  • System.Drawing
  • System.Transactions
  • System.Xml.XslSystem.Xml.Schema
  • System.Net.Mail
  • System.IO.Ports
  • System.Workflow
  • System.Xaml

移植にあたって

既存の.NET Framework向けのアセンブリがどのくらい移植しやすそうか解析するツールがあるみたい:

で移植の流れとしては、

  • とりあえず .NET Framework 4.6.1にしとくと.NET Coreとの差が少ない。
  • 元のコードは .NET Framework ターゲットのまま、このツールを掛けつつ修正してとか繰り返すのがおすすめ。
  • .NET Coreへの完全移行じゃなくて、Core/Framework両方で使うとかもあるだろうからその場合はShared SourceとかPCLとかを活用

とかそんな感じ。


Windows 10アプリ開発に関する近況 (Astoria開発中止とか)

$
0
0

以下のブログがちょっと話題になっていますが。

An Update on the Developer Opportunity and Windows 10

Windows 10アプリ開発に関する近況的な話で、Xamarinとか各種ブリッジ(他の環境向けアプリからの移植)とかの現状を説明しているんですが。

Xamarin買収の話と同時期に出したせいとか、ブログの内容がいまいちとか色々あり… なんか変な印象になってるなぁとか、ちょっと不安な感じ。文章読んでて受ける印象的に、これ、そんなに技術に詳しくない広報の人が、技術者から聞いた内容を元に書き起こしてて、微妙に正確じゃない表現になってるんじゃないかなぁとか思ったり(Windowsチームはそれをやらかしそう、という偏見もあり)。

Bridge for Android (コードネーム「Astoria」)の開発停止

この記事、「マイクロソフトはBridge for Android (Astoria)の開発停止を認める」とかいう話題にされてしまっていて。それはこのブログの本題じゃなかったと思うんだけどなぁ…

まあ、去年の11月にはそういう話が出ていたんですが、 確かに、ブログで明示的に停止した話が書かれたのは初めてなのかな… そのせいで、なんか騒動になっているみたいで。

ですが、 Xamarin買収のタイミングで変な文章を書いたので「AstoriaとXamarin、2つは必要ない」という主張だと誤認されたり、 Bridge for iOSとの関連の説明が下手なせいで「ブリッジ技術にAndroid向けとiOS向けの2つは必要ない」と取れる文章だったり、 なんか変な感じ(なので、これ、非技術者な広報担当者が書いてるなぁという印象です)。

クロス開発と、ブリッジと

そもそも、クロス開発と各種ブリッジは相補的というか、逆のことをやっているというか。

クロス開発は、これからスマホ向けアプリを作ろうとする人に、UWP (Windows 10 Mobile)も選択肢に入れてもらう(iOS、Android、Windows全部をターゲットにしてもらう)ためには何を使ってほしいかという話。マイクロソフトが提供する選択肢としては、

  • Visual C++ Cross-Platform Mobile
    • C++でクロス開発するためのプロジェクト テンプレートとかデバッガーとか
    • 今、Android開発に関してはJavaにも対応してたり
  • Apache Cordovaと、そのVisual Studio対応
    • JavaScriptでWeb的に(UIもHTMLで書いて)ネイティブ アプリ化する
  • Xamarin
    • Mono ベース/C# でクロス開発

とかがあったわけです。

一方、ブリッジは、特定環境向けに作られた既存のアプリをUWP化してもらうための技術。開発が続いてるのは、

  • Web Bridge (コードネーム Westminster)
    • Web技術をそのままUWP化
  • Win32/デスクトップ向け.NET移植 (コードネーム Centennial)
    • デスクトップ アプリをサンドボックス動作させるだけっぽい
  • Bridge for iOS (コードネーム Islandwood)
    • Objective-Cで書かれたiOS向けコードをビルドして、UWP化できる機能

など。

で、今回、開発停止が正式になったというのが、以下のAstroia

  • コードネーム Astoria
    • Windows 10にAndroid互換レイヤー(JVM + Android API)を載せて、エミュレーションしようという技術
    • ここが Bridge for iOSとの差。ソースコード レベルでの移植じゃなくて、バイナリをそのまま動かそうとしてた

Java for Android対応

一方で、今のVisual Studioって、JavaでのAndroidアプリ開発には実は対応していたり。

これ、しかもちょっと面白いのが、C++チームが保守してる(上記ブログはC++チームが書いたもの)という事実。

今、マイクロソフト内のC++チームが負ってる債務は「クロス開発」のようです。 その結果、Android開発はC++チームの範疇で、Java for Android対応もC++チームの債務。

という背景から、Androidからのブリッジも、Bridge for iOS (Objective-Cからのビルド)と同じく、JavaソースコードからUWPを作る機能であるべきなんじゃないかなぁという感じ。

で、実際、Astoriaの開発停止の話が出たのって、このJava support in Visual Studio for Androidが出たのと同時期だったりします。

結局のところAstoria開発停止の理由

実際のところは中の人に聞いてみないとわからないものの、僕が受けた印象としては、以下のような話だったんじゃないかなぁと。

  • Xamarinとの関連
    • 「Xamarin買収の話題をきっかけに、いったん現状報告しとくか」程度であって、Astoria開発停止とは完全に無関係
  • Bridge for iOS との関連
    • 本来いうべきこと: Bridge for iOS同様、ソースコードからのビルドであるべきではないか。互換レイヤー提供によるエミュレーションと、ソースコードからのビルドの2方式あるのは混乱の元
    • ブログの文面: Bridge for iOSに注力する。2つのブリッジ技術があるのは混乱の元
  • 実際あり得そうな本来のAstoria開発停止理由
    • Java support in Visual Studio for Android をベースに、Javaソースコード レベルでUWP化に対応するのが筋
    • ここが「計画としてはあるけどまだめどが立ってない、あるいは、//build/辺りでの発表目指してる」とかで今は何も言えない
      • 言えない(というか、できるかどうかもわかんない)ことをお茶を濁した結果がブログの微妙な文面

伝言ゲームで文面が変になったり、言えないことをお茶を濁して余計言っちゃいけない感じの文章になったり、まあ、割かしよくあることだと思います…

ピックアップRoslyn 3/1: position-to-propertyマッチ

$
0
0

久々にMads降臨(C# チームのLanguage Design Meetingの議事録投稿)。

3つの言語機能を紹介しているんですが、共通して「position-to-propertyマッチ」というのが必要になります。 このposition-to-propertyマッチを許す「主義」を採用することに決めたという報告です。

position-to-propertyマッチ

簡単に言うと、例えば以下のようなクラスがあったとき、

public class Person
{
    public string FirstName { get; }
    public string LastName { get; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

コンストラクター第1引数のfirstNameとプロパティのFirstNameには1対1の対応があります。同様に第2に引数lastNameとプロパティLastNameもです。 こういう、1対1の関係を、(先頭の1文字の大小の差は無視して)名前をベースに調べて、

  • FirstNameというプロパティと、コンストラクターの第1引数を同一視する
  • LastNameというプロパティと、コンストラクターの第2引数を同一視する

というような、引数位置(position)とプロパティ(property)の間の同一視を用いようという意味合い。

結構これを認めるのはC#としてはチャレンジになります。「頭文字の大小を無視」も、「名前の一致を見て同一視」も、これまで結構避ける主義でした。

ただ、以下に紹介する機能を、既存の型に対しても使えるようにしようとすると、どうしてもこういう仕組みが必要になります。

3つの新機能

position-to-propertyマッチを使う3つの新機能は以下の通りです。

  • immutableオブジェクトに対するオブジェクト初期化子
  • with式
  • 位置指定のパターン(positional pattern)

immutableオブジェクトに対するオブジェクト初期化子

先ほど出したPersonクラスみたいなimmutableなオブジェクト(プロパティがget-onlyで、値の書き換え不能)を初期化したい場合、コンストラクター引数に値を渡す必要があります。でも、オブジェクト初期化子構文を使っての初期化を行いたいことがあります。なので、

new Person { FirstName = "Mickey", LastName = "Mouse" }

というコードを、

new Person("Mickey", "Mouse")

に置き換えようという機能を提供したい。

で、このためには、どのプロパティがどの引数に対応するか知る必要があります。

with 式

immutableなオブジェクトは、値の変更も面倒になります。書き換え不能なわけで、わざわざ、一部の値を変更したうえで、新しいオブジェクトを作る必要があります。この面倒を軽減するために、with式という構文が提案されています。

以下のような書き方で、

p with  { FirstName = "Minney" }

以下のようなコードを生成します。

new Person("Minney", p.LastName)

こちらも同様に、プロパティに対応する引数を知る必要があります。

位置指定のパターン

C# 7に向けて実装中のパターン マッチング機能で、以下のようなコードが書けます。

p is Person("Mickey", *)

これは、pの型がPersonかつ、FirstName"Mickey"ということを調べる式です。

第1引数がfirstNameなので、対応するプロパティFirstNameの値を調べます。

こういう書き方は位置指定のパターン(positional pattern、あるいは、position-based pattern)といって、コンストラクターの逆操作です。

p is Person("Mickey", *) ⇔ new Person("Mickey", "...")

一方、以下のようにプロパティ指定でのパターン(property pattern)もあって、こちらはオブジェクト初期化子の逆操作になります。

p is Person { FirstName is "Mickey" } ⇔ new Person { FirstName = "Mickey" }

そして再三になりますが、この位置指定のパターンにもposition-to-propertyマッチが必要になります。

もちろん、position-to-propertyマッチに頼らない明示的な挙動の上書きも用意する(GetValuesメソッドや、is演算子のオーバーロードなどが候補になっている)つもりだそうですが、既定の挙動としてはposition-to-propertyマッチを使いたいとのことです。

既存の型への新構文の適用

position-to-propertyマッチを認めるというのは、結構、C#としては主義の変更というか、大幅な妥協ではあります。 (当然、issueページのコメント欄は、結構な割合でネガティブなコメントが埋まっていたりします。)

最初は、レコード型という新しい構文を用意して、その構文で作ったクラスや構造体で、上記の3つの構文を使えるようにする(使うための特殊なメソッドを生成する)つもりで考えていました。

が、その場合、既存の型には上記の便利な構文が使えないことになります。そして、すでに世に出回っている多くのコードに対して逐一「レコード型で書き換えろ」なんて言えるはずもありません。

なのでこの妥協、この主義変更ということになります。 実際のところ、世に出ているコードの多くが、コンストラクター引数とプロパティの名前を(頭文字の大小除いて)同じにしていたりするので、 実用性を考えるとよい妥協しどころではあります。

ピックアップ Roslyn 3/3: タプル ベースのposition-to-propertyマッチ

$
0
0

一昨日のの補足。

先日は以下のようなLanguage Design Notesが出てたわけですが。

コンストラクター引数とプロパティの名前の一致を見て、何番目の引数がどのプロパティに対応するかを調べる(position-to-propertyマッチする)方針を使おうという話。 もちろんいろんな対案あった中で、今、こういう方針に傾いてるという話なんですが、そういう過程抜きに「名前の一致を見る」の話だけしたので多少炎上中。

ということで、対案の1つ、タプルを使ったパターンの話も公開されました。

以下のようなメソッドを用意することで、position-to-propertyマッチしようというもの。 拡張メソッドでもいいことにしておけば、既存のクラスの拡張もできます(ただし、その拡張メソッドを書くのは手動。大変めんどいはず)。

public class Person
{
  ...
  public (string FirstName, string LastName) GetValues() { ... }
  public Person With((string FirstName, string LastName) builder) { ... }
}

with式みたいなものの実現には、既存の言語構文だけでやるならいわゆる「ビルダー パターン」を使ったりします。 そのためにはビルダー用のクラスを1個余計に作らないと行けなくて、余計なメモリ アロケーションが発生したり、余計なクラスを書く手間が掛かったり。

でも、タプル型を使えば、タプルはmutableな構造体なので余計なアロケーションは起きない。 それに、新しいクラスの追加も必要なくて、手間は多少マシになる。 タプルは元々、引数位置と名前の対応関係を持っているので、黒魔術的な特殊処理なしでposition-to-propertyマッチできるはず、ということになります。

とはいえ、以下のように、悪い面もあります。

  • 既存の型に対してそのままでは使えない。GetValuesWithなどの追加(拡張メソッドでもいいけど、手動での追加)が必要
  • オブジェクトの分解(GetValues)やwith式(With)はインスタンス メソッドになるのでvirtualにできても、新規インスタンス作成ではできない
  • (レコード型などの新構文で)コンパイラーが自動生成するコードが増える
  • タプル型という、別の新構文に強く依存することになる(複雑度が増す)

というような話があっての、先日の「名前で解決」の流れになったという話です。

ピックアップRoslyn 3/18

$
0
0

C# 7に取り込む範囲、ある程度決まったみたい

作業リストが更新されてた。

前はあって今消えてるものは単に「7からは外す」という意味。 まだ最終決定でもないんで、ここからまた増減はあるはず。

個人的な印象としては、現状でもそこそこ動いているものだけ残してる感じ。 たぶん、「年に1回リリース」、つまり、今年中のC# 7リリースがかなり現実味ありそう。

ということで、まだちょっと検討が要りそうなものはリストから抜けました。 待ち遠しいけども先送られたのは「非同期シーケンス」と「非null参照型」あたりですかね。

レコード型の仕様書

レコード型の仕様書がやっとできてた。future ブランチにはマージ済み。

expression-bodied な set/get、コンストラクター

set, get 個別に、=> を使った短縮形のプロパティ定義を書けるようにしてほしいとか、そういう要望が前々から上がっていたわけですが。

C# 6の時にも検討されたものの、「要望があるのはわかるけど、そこまで需要高くないし後回し」扱いされていたものです。

それに対して、C# チームの外から pull request が来て、C# チーム的にも「それをベースに実装するか」という流れになっている模様。

サロゲートペア識別子対応

日本人的に、ほしければ「Add your reaction」で +1 だけでもつけといた方がよさそうなものが。

サロゲートペアになってる文字でも、文字カテゴリーが letter になってるんだったら識別子に使えるべきじゃないかという話。

要するに「𩸽」(ほっけ。U+29E3D)とかの話。

C# 的には、letter系のカテゴリーに含まれている文字を識別子に使えるという仕様になっています。 ただ、.NETが内部的に16ビット(UTF16)で文字列を持ってるせいで、サロゲートペアになってる文字はカテゴリーを正しく判定してもらえない。

要するに、以下のようなコードを実行すると、結果はSurrogateになります。

char.GetUnicodeCategory("𩸽"[0])

とはいえ、以下のように、charじゃなくてstringを受け付けて、サロゲートペアな文字でも使えるオーバーロードに書き直せばちゃんと判定できます。 𩸽の場合はOtherLetter。

char.GetUnicodeCategory("𩸽", 0)

ってことで、

  • C# 実装なRoslyn的に、実は判定自体はできる
  • でも、2文字見ないといけなくなってそれなりにコンパイラーに負担が掛かる
  • それで使えるようになる文字というと、日本語的には𩸽みたいなレアな文字
    • このissueページで言われてるのは「シュメール語の文字を使いたい」みたいな要望

という感じ。

それでも、この手の文字を識別子に使いたいですか?使いたいなら、reactionしておきましょう。

Visual Studio 2015 Update 2がRTM & Visual Studio "15" Preview

$
0
0

昨日は夜更かししていたわけですが。

なんか今回は「本来はWindowsのイベント」らしさがあり、ほんとにWindowsの話題ばっかり。 開発ツール系の話が初日キーノートに出てこないという。 内心「やべぇ、しゃべることねぇ」とかおびえながらのひな壇芸人やってました。 危うく、ただ池澤あやかさんに会いに行くだけのミーハーになるところでした。

開発ツール系は2日目の今晩のキーノートで話すんですかね。確かに最近そういう構成になってること多い。前の方にコンシューマー受けするもの、後ろの方に開発系。

そして、キーノートでまったく触れられないまま、さらっとMSDNブログで公開されるVisual Studio。

Visual Studio 2015 Update 2

そういえば、プレビュー版、RC版が出たときにあんまり取り上げてなかったなぁと。

C# に関連する新機能は4点ほど

  • ソースコードを選択 → 右クリックメニューの「Execute in Interactive」から、C# Interactiveにコードを送れる
  • Add Using (using ディレクティブの追加)に対するあいまいマッチング
  • アナライザーAPIの性能改善
  • 標準提供のリファクタリング機能にいくつかの新アクション

上の2つは簡単に触れておこうかと。

Execute in Interactive

ソースコードの1部分の実行結果を今その場で知りたいときに便利。

ではあるんですが、これ、プロジェクトのコンテキストを取り込んでくれない(そのプロジェクト内で自分で定義した型は使えないし、参照してるライブラリもCV# Interactiveからは参照されない)ので微妙に不便。標準ライブラリ内のクラスしか使えないんですよね。「Json.NETのシリアライズ結果の挙動を知りたい!」とかもできない。計画上はNuGetパッケージの参照とかはC# Interactiveウィンドウ内からできるようにしたいって話があった気がするので、まあ、今後に期待ですかね。

Add Using あいまいマッチング

「usingディレクティブってソースコードの上部にしか書けないからうざい。今まで使ってなかった名前空間の型を新たに使いたくなった場合、いちいちに上に移動するのがめんどくさい。」という不満にこたえる「Add Using」機能ですが、これまでだとクラス名を正確に打たないと「Add Using」できなくて、微妙に不便でした。

というのも、IntelliSenseであれば、

  • 全部小文字で打っても補完でCamelCaseなメンバーを見つけられる
  • 途中まで打てば補完で長い名前を打てる

という機能があって、もうさぼり癖がついてるわけです、C#開発者は。 それが、「Add Using」したければクラス名を正確に全部書けとか、無理。

挙動を見てる感じ、

  • 全部小文字で打っても認識
  • 文字が1・2文字まで間違ってる/足りてない状態でも認識
    • 単語の長さによるっぽい

という感じ。 streem(Stream)、dianostic(Diagnostics)とかそんなのがちゃんと補完されます。 スペルを正確に覚えるのが面倒なときに便利。 queueみたいな2文字違いどころじゃないレベルの単語が相手だと少々厳しいですが…

全部小文字で打って、Add Using

Visual Studio "15" Preview

"15"はもちろん内部バージョンのことです。Visual Studio 2015が"14"。つまり、次期バージョンのプレビュー。

これまでだと、マイクロソフトの製品って2・3年サイクルでリリースしてました。直近のC#でも、2010でC# 4→2012でC# 5→2015でC# 6です。 最近徐々にリリースサイクルを縮めたがっているわけですが、なので、今年中のリリースが期待されます。

あと、インストーラーが2つあります。今まで通り、isoファイルで丸ごとの提供があるインストーラーと、「lightweight」なインストーラー。

C# 的には、まあ、GitHubのRoslynリポジトリを眺めてると、futureブランチに結構C# 7の新機能がマージされだしておりまして、「おっ、ここまでは近々バイナリでのリリースがあるのかな」などと眺めておりました。

実際大体その通り。1・2週前のプルリクまではVS "15"に入った感じですね。

以下の機能が動きます。ただし、今、C#7の文法を試すにはちょっとしたトリック(条件コンパイルシンボルに __DEMO__ を追加する)が必要になります。

  • ローカル関数(nested local function)
  • パターン マッチング(pattern matching)の一部
  • ref戻り値/refローカル変数(ref returns/ref locals)
  • 2進数リテラル(binary digit)、数値セパレーター(digit separator)

(ちなみに、リリースノートに書かれてないやつも、GitHub上で実装っぽいものがあったものは一通り試しました。その結果、2進数リテラルが動いてることを確認。)

この3/31リリースのプレビュー版で動くC# 7コード、GitHubにサンプルを上げておきました。

DEMO 条件シンボル

今のところ、futureブランチにしかないような新文法は、コンパイラー オプションを追加しないと使えない状態になっています。 で、Visual Studio上からどうやってそのオプションを追加するの?という話なんですが… 追加できないです。対応追いついてないようで。

じゃあ、どうやって上記サンプルは動かしてるかというと、抜け道がありまして。 「プロジェクト設定で__DEMO__という名前の条件コンパイル シンボルを定義しておく」という、一時しのぎ感溢れる見事な対応。

__DEMO__ 条件シンボル

名前通り、デモで見せるときに使ったんでしょうね。

ローカル関数

↓こんなやつ。

private static void LocalFunctions()
{
    int F(int n) => n >= 1 ? n * F(n - 1) : 1;
    Console.WriteLine(F(5));
}

まあ、public void X()に対してprivate void XInternal()みたいなのを別途書くこと、たまにあったじゃないですか。 それが必要なくなります。

これまでも、ラムダ式を使えば似たようなことはできましたが、以下の点でローカル関数の方が有利になります。

  • 再帰呼び出しが素直に書ける
  • デリゲート変数への代入が省ける
  • ローカル変数のキャプチャがちょっと賢い
    • ラムダ式: クラスのフィールドに昇格する。ヒープのアロケーションが発生
    • ローカル関数: 構造体のフィールドにして、ref引数で関数に渡される。ヒープ除け

パターン マッチング(一部)

パターン マッチング自体は、最近Build Insiderに寄稿したんでそちらを参照していただくとして。

このうち、位置指定パターンだけは未実装。 次回の記事で書く予定ですが、位置指定パターンだけはちょっと実装が面倒とういうか、 レコード型やタプル型など、他の新機能も合わせて詳細を詰めないといけないので、少し実装が後回しになっています。

まあ、型パターンだけでも使えれば結構便利なはず。

ref戻り値

↓こんな感じ。

struct Buffer<T>
{
    public int BaseIndex { get; }

    private readonly T[] _array;

    public Buffer(int baseIndex, int count)
    {
        BaseIndex = baseIndex;
        _array = new T[count];
    }

    public ref T this[int index] => ref _array[index - BaseIndex];
}

まあ、ほとんどの開発者は直接は使わなさそうですかね。 パフォーマンス改善に期待できる機能です。 ライブラリ作者がこれを使うことでパフォーマンスが上がり、間接的には全ての開発者への恩恵が期待されます。 というか、C# コンパイラー自信のパフォーマンス改善が結構見込めそう。

これに限らず、パフォーマンス改善系の機能追加はちらほら追加されていきそうな雰囲気です。

2進数リテラル/数値セパレーター

↓これは大変わかりやすく。

var b = 0b1000_0001;
Console.WriteLine(b);

こいつはC# 6の頃から新機能候補に挙がってましたし、結構前から実装済みだったはず。CoreFxの方のソースコード見てたらそこらじゅうですでに使われてたり。 前からあるから、今回リリースノートに書き忘れたのかなぁとか思ったり。 「そんなに強い関心があるわけじゃないけど実装が簡単だから実装済みです」、「0bでいいのかとか_でいいのかとか議論の余地もあるし、もう少し寝かせるか」みたいな立ち位置のはず。

lightweightインストーラー

全部の機能はiso版のこれまで通りのインストーラーでないとまだ使えないらしいですが。 それとは別に、今後に期待がかかるlightweightインストーラーってのが提供されました。

これまでの「webインストーラー」と何が違うかというと、

  • 最小構成だと300MB程度でインストールできる
    • 必要な機能は必要に応じて拡張マネージャーで入れる
  • どうも、レジストリを汚さないみたい
    • 既存のVisual Studioを立ち上げっぱなしでもVS "15"をインストール可能
    • 1台に複数インストールとかもたぶんできる
      • プロジェクトごとに別の拡張入れた状態のVSを作るみたいなのもたぶん

という感じ。地味に、大きな変化だったり。

ピックアップRoslyn 4/10

$
0
0

「C# 7」に入る範囲がそろそろ決まってきた感じ。

C# Design Notes for Apr 6, 2016 (Tuples, Recursive patterns)

久々に言語デザインミーティングの議事録が。

タプル型と、再帰的なパターン(位置指定パターン・プロパティ パターン)の詳細がだいぶ決まってきたっぽい。

タプル型は↓こんな感じ。

  • メンバーの数と型が一致していたら、名前は無視して同一視する(代入可能)
    • box化・unboxしても同様の変換ルール適用可能
    • メンバーが int → long みたいな暗黙的型変換できる場合でも、タプル型の自動変換はいったんしないことにする(将来はわからない)
  • 無名タプルも作れる(メンバー名指定なし)
  • 匿名型の new { p.X, p.Y }みたいに、名前の射影(X, Yという名前を引き継ぐ)あり
  • タプル型に対する拡張メソッドも作れる
  • タプル型引数の規定値も指定できるようにしたいけど、そのためには何か新しい属性が必要になる(ので、いったん据え置きになりそう?)
  • 0-tuples, 1-tuplesも検討したい
    • それぞれ、C#チーム内ではnuples, wonples (null+tuple, one+tupleの造語?)と呼んでるみたい
    • nuplesは、要するに「ユニット型」。()で書き表せそう
    • wonplesが難しそう。(Type)(value)も現在のC#で有効な構文になっちゃってるんで
  • タプル型戻り値を、out引数みたいな感じで、メンバー名で代入可能にはしない。return使え

再帰的なパターンの方は、もしかしたら全部やC# 7ではやらないかも。段階的に便利にしていくのでもいいだろうし、後からの追加に耐えれるようにC# 7を作れそう、とのこと。

Language Feature Status

C# 7として出したいもの、だいぶ絞られてきたみたい。状況のまとめページができてます。

概ね、こないだのbuildでデモでプロトタイプが動いてたものに絞った感じ。リリース時期が大まかには決まってきたのかな?この絞り方(今ある程度動いてるものだけをまず出す)の感じからすると、Windows 10のレッドストーンと同時期?

Source Generators

メタプログラミングがらみ、ソースコード ジェネレーターのドキュメントができてた。

これはほんと一刻も早く試したい…

C# as a High-Performance Language

C# vNextのパフォーマンス改善系の提案まとめページが。

Build Insiderでやってる連載の次回のネタ、パフォーマンスにしようかなぁ。

Roslyn自体がパフォーマンス面に関して相当シビアだったり、ゲーム方面でC#が注目されてたり、.NET Coreがベンチマーク向上を頑張ってる真っ最中だったり、今、結構こういう機能が求められています。

ピックアップRoslyn 5/4

$
0
0

4月に紹介したLanguage Feature Status、だんだんはっきりとC# 7、VB 15に入りそうな範囲が結構絞られてきた感じ。

最近は、タプル型がらみに注力してる感じがします。

パターン マッチングも部分的に実装

これまで出てたアイディア全部を一気にC# 7に入れるんじゃなくて、将来的な拡張を阻害しないように気を付けつつ、部分的に実装しようという感じになってる様子。

上記リンクのうち、「Part 1 (targeting future)」になってる方がC# 7に入りそうなやつで、「Part 2 (to remain in features/patterns)」に入ってる方がそれより後のバージョンになりそうなもの。

要するに、C# 7としては、いったん、単純な型による分岐だけを実装するみたい。以下のものはその後の予定。

  • 再帰的なオブジェクト分解の構文
  • let ステートメント
  • match 式
  • throw 式

C# Design Notes (タプル型関連)

4月中にあったC# Designミーティングの議事録。タプル型関連の議題が多かったみたいです(あと、out varの話が少し)。以下のような内容。

  • ValueTuple以外の型
    • C#のタプル型の実装に使われるValueTuple構造体の他に、既存のTupleクラスとか、あと、KeyValuePairなんかも性質としてはタプルっぽい。これらを統一的に扱いたい
  • タプル型の分解(代入、宣言、パターン マッチング)用の構文案
    • (int x, int y) = Get();的なのか、(int, int) (x, y) = Get(); 的なのか、いくつか候補あり。今のところ前者が有力
  • (byte, short)から(int, int)みたいな、メンバー単位で暗黙の型変換がある場合の、タプル型間の変換
    • 認める方向で検討中。ただ、コンパイラーが頑張ることになるし、C# 6と7でオーバーロード解決ルールとかが変わっちゃう問題がある
  • (C#の構文糖衣としての)タプル型と、構造体のValueType
    • null許容型がint?でもNullable<int>でも使えるように、タプル型も(int, int)でもValueTuple<int, int>でも使えるようにしたい
  • パターン マッチングとの兼ね合い

ちなみに、そのValueTuple構造体ですが、ついにcorefxの方に入ったみたい。

(ちょっと前までは、roslynリポジトリ内でだけ実装してた)

非同期メソッドの戻り値を任意の型に

今、Taskクラスしか返せない非同期メソッドに、任意の型を返せるように拡張したいという話。

あと、非同期ストリーム(awaityieldを両方含めて、IObservableとかIAsyncEnumerableのような戻り値を返せるもの)の実装もまとめてディスカッション中。

これは、Language Feature Statusの「(C# 7.0 and VB 15) + 1」にすら並んでないんで、さらにもうちょっと先になりそうなんですかね。


ピックアップRoslyn 5/12

$
0
0

なんでも拡張

拡張メソッドは便利な構文なわけですが、インスタンス メソッドしか拡張できないのが残念なところです。拡張プロパティとかも作りたいことがあるし、静的な拡張(静的メソッドも既存のクラスに対して追加したように見える構文)もほしかったりします。という、なんでも拡張できる構文の案。

今のところ、以下のような構文で検討中。

extension class クラス名 : 拡張したい型
{
    // ここにメンバーは、拡張したい型の拡張メソッド、拡張プロパティなどになる
}

C# Design Notes (タプル型関連 再び)

前回C# Design Notes for Apr 12-22, 2016に引き続き、タプル型関連。

  • 分解
    • (x, y) = tuple; みたいなのを、tuple.Deconstruct(out x, out y); みたいなメソッド呼び出しとして解釈したい
    • タプル型専用の特別な構文にしないために、インスタンス or 拡張メソッドを通したい
    • ちょっと前までGetValueって名前を検討してたけど、一般的過ぎてすでに使われてそうなので、Deconstructメソッドにする
    • 要素の値を返すのはout引数にする。タプル型を分解するのにタプル型を返すわけにもいかないので
  • switchステートメントでの変換
    • 既存のswitchだとintとかstringしか受け付けないので、intとかへの暗黙的型変換できる型は変換結果で解釈されてた
    • 破壊的変更にならないようにするために、暗黙的型変換を定義した型は、今後も変換結果で解釈する
    • なので、そういう型(例えばintへの暗黙的型変換を持ったConst型)は case Const(int i): みたいなcaseにマッチしない(case 0:とかにはマッチする)
    • あんまり起きない状況だし、破壊的変更を避ける方を優先
  • タプル型間の変換
    • 「要素数が一致していて、各要素が暗黙的型変換できるなら、タプル型間でも暗黙的型変換できる」ってルールにするっぽい
  • タプル風のインスタンス生成
    • 任意の型に対して、左辺から型が推論できるなら、new (x, y)みたいな書き方でインスタンス生成できるようにする

最後の「タプル風インスタンス生成」はちょっと補足。

元々の発想は、「分解の構文をDeconstructメソッドを通すことで汎用化したんだし、構築の構文も汎用化すべき」というもの。タプル構築と、コンストラクター呼び出しを紐づけたいということになります。

が、例えば、その発想で行くと、以下のように、なんか直観にそぐわない「タプル型リテラルからの構築」ができてしまう。

Dictionary<int, string> d = (16, EqualityComparer<int>.Default); // さすがにこれは気持ち悪い

代わりと言ってはなんだけど、以下のような、newの後ろの型の省略を認めようという感じになってるみたい。

Point p = new (3, 4); // new Point(3, 4) と同じ
List<string> l1 = new (10); // 引数0個 or 1個でも大丈夫
List<int> l2 = new () { 3, 4, 5 }; // コレクション初期化子との併用もできるけど、() は省略できない

要するに、結局、左辺からの型推論みたいな構文を追加することになりそう。

【開催報告】 //build/ 振り返り勉強会

$
0
0

5/21(土)に勉強会を開いてました。 今回はまどすた(旧めとべや)との共同開催で、//build/の振り返りでした。

以下、当日資料の一覧です。

ルームA (サーバー部屋)

//build/ まとめ(サーバー編)

祝GA、 Service Fabric 概要

Bot FrameworkでBot入門

Introduction to Azure Functions

Bash on Ubuntu on Windows、ちょっとだけWindows Subsystem for Linux

C# 7

ルームB (クライアント部屋)

//build/ 2016現地で感じたクライアント開発の潮流

Holo World ~ はじめの一歩 ~

Build/Evolve 振り返り

デスクトップ アプリがこの先生きのこるには

デスクトップ アプリの生存戦略 (Desktop App Converter)

VR元年のゲーム開発

Cutting Edge!

2進数リテラルと数字区切り文字

$
0
0

C# 7思い出話

C# によるプログラミング入門に、ちらほらとC# 7の話題を書き始めたわけですが。

まあ、入門なんで仕様として固まったものだけを書いていくつもりです。ある程度固まりそうな段階まで書かないし、結局予定から漏れたものは修正したり。

一方で、その仕様が固まるまでにあった流れなんかも、ブログに残しといてもいいかなぁとか思ったり。

ってことで、「C# 7思い出話」なんていうカテゴリー付けて、ブログでも書いてみようというのが今回の話。 さしあたって、今、入門に書いたのが、

の2つなので、今日はこの2つ。

2進数リテラルと数字区切り文字

こういう機能。

var million = 1_000_000;
var abcd = 0b1010_1011_1100_1101; // 特に2進数リテラルで有用
var abcd2 = 0xab_cd;              // 16進数リテラルにも使える
var x = 1.123_456_789;            // 浮動小数点数リテラルにも使える

2進数リテラルと数字区切り文字の2つはセットですね。 2進数って普通に書いたらむちゃくちゃ大きな桁数になりますし。 そりゃ、区切らないと読めた代物じゃない。

この2つの機能、「C# 7」としては「気が付いたらいつの間にか実装があった」って感じです。 特に「実装したよ」アナウンスもなく、pull-requestも見かけず。

そもそも、「C# 7の最初の設計ミーティング」でちょこっと「ページ内検索してみたら確かに書かれてる」程度の地味な取り上げられ方してただけ。機能的にも小さなものなので、提案ページもすごく簡素。

それも当然でして、この機能はC# 6の頃からあったから。 要するに、「C# 6の頃から試験的な実装あったけど、結局C# 6には入れなった」というもの。 仕様的に何か問題があったわけでもなくて、単純に「優先度低、スケジュール的に後回し」。 という話が、今稼働してるGitHubのリポジトリじゃなくて、昔懐かしCodePlex時代にありました。

まあ、こういう、低コスト・低リターン機能は後回しになりがち。

実装するのは低コストと言っても、仕様的に問題ないかをよく考えたり、実際試してみる期間を設けるのはそれなりに大変です。 CodePlex上で、以下のようなディスカッションがあった記憶があります。

  • 区切り文字は _ でいいの?
  • 1010 1100みたいにスペースで区切らせてよ
    • それは字句解析的に面倒で、コストかかりすぎる
  • 8進数リテラルも入れてよ
    • あっても使わないだろ、実際
      • chmodで使うよ
    • C言語の0始まりは紛らわしいし、octalだからって0o (ゼロ、オー)も0とoが区別つきにくいし
  • そもそも、16進数リテラルの0xもなんなの、Xって。hexの3文字目って

簡単な機能であっても、なかなかめんどくさい感じの話に。

ピックアップRoslyn 5/29

$
0
0

拡張メンバー

Design Meetingで拡張メンバーの検討をしてたみたい。 (拡張メンバー = 初期検討段階で「extension everything」(なんでも拡張)って言ってたやつ。拡張メソッド以外に、プロパティとかも拡張できるようにする構文)

現状、以下のような感じ。

  • extension classってキーワードで、通常のクラスを継承したような構文で作る
    • 定義したメンバーは拡張メソッド同様、静的メソッド化される
    • プロパティは、「インデックス付きプロパティ」(ILレベルとかVBにはある。C#のレベルで使ってないだけ)に展開するのがよさそうだけど、現状のC#では認めてないものなのでちょっと悩ましい
  • インスタンス メンバー風の拡張だけじゃなくて、静的メソッドの拡張も足せる
  • コンストラクターも足せる
  • 演算子をどうするかは悩ましい
    • 四則演算とかはいいと思うんだけど
    • == とかが怪しい
  • Personクラスの拡張Enrolleeがあったとして、Personの通常のインスタンス メンバーと、拡張の方のメンバーを呼び分ける構文がほしい
    • 優先されるのは通常のインスタンス メンバー
    • たぶん((Emrollee)person).Supervisorみたいなキャスト構文でやる

コンパイラー組み込み

「時々C#にもインライン アセンブラーがほしい」問題に対して、 別解法の提案。

C#では書けないもの

まず、「ILを使えば書けるけど、C#では書けない」みたいなのの例。

  • CLRがやってるみたいなネイティブ コードとの相互運用をビルド時に静的に作ってしまおうと思うと、いくつかC#では書けない命令が必要
  • infoof(information ofの略。typeofと同じノリでMethodInfoとかを取る)相当の機能をライブラリでやろうと思うとldtoken命令が必要
  • スライスを作るのにC#では書けない機能が必要

インライン アセンブラーはやらない

  • 時々しかない要件のためにILインライン アセンブラーを実装するのはコストに見合わない
  • というか、混ぜるのよくない。C#コンパイラーとILアセンブラーは別ツールとして、別チームが個別開発すべき

別解法の提案

で、提案してるのが「コンパイラー組み込み」(compiler intrinsics: コンパイラーが内在して持ってる実装)。

いくつかのC++コンパイラーは、プログラマーがSSE命令とかAVX命令みたいな特殊な命令を使えるように、コンパイラー組み込みの特殊なメソッドを提供してたりします。 C#でもそういう特殊なメソッドを用意して、上記のような通常のC#では書けない場面に対処すればいいんじゃないかという提案を出してきています。

文法的にはexternメソッドを使うだけ。CompilerIntrinsic属性を付けることで、ネイティブDLL中のネイティブ メソッドを呼ぶ代わりに、コンパイラーが直接その場所にIL命令を出力するというもの。 これなら今から新文法について考える必要もないし、簡単に目的が達成できそう。

bool型やenum型のswitchの完備性

bool型にはtruefalseしかないはずなんだから、以下のdefault句は不要にできないかという話。ご意見求む状態。

bool b = ...;
switch (b)
{
    case true:
    case false:
        break;
    default:
        break; // warning: unreachable code?
}

これ、昔から要望としては頻出なんですが、できない理由もあります。ILは結構低級機能を提供しているので、bool型の変数を無理やり書き換えて、trueでもfalseでもない値を作れて、上記default句に来ちゃう場合があったり。 というか、C#でも、以下のような書き方でそういう値を作れます。

それに、後方互換性を考えると、既存のswitchには警告も出せないです。

という背景の中、今後導入予定のmatch式(switchの式バージョン)ではこういう普通はあり得ないdefault句に対する警告がほしいですか?という質問。

言語サポート付きのobsolete

今、obsolete (廃止したい、もう使ってほしくない)なメンバーにはObsolete属性を付けて対処しています。 でも、この属性ベースのやり方じゃなくて、C#の言語機能としてobsoleteキーワードが必要かもという話が。

シナリオ的には以下のようなもの。

// シナリオ 1:
int f(string s);                 // ライブラリv1がこいつを持ってる
int f(string s, bool b = false); // v2でこれに変えたい
// バイナリ互換性のためにf(string)は消せない
// でも、今後、オーバーロード解決時に、f("") で優先的に f(string, bool) の方を見てほしい(今は無理)

// シナリオ 2:
float g();  // ライブラリv1がこいつを持ってる
double g(); // v2でこれに変えたい
// バイナリ互換性のためにfloat g()は消せない
// でも、今後、double g()を使いたい(呼び分けどころか今はそもそも定義すら不可能)

これに対して、v1側にobsolete修飾子を付けることで、v2側の新メソッドの追加・オーバーロード解決できるようにしたいとのこと。

TryRoslyn

Roslynリポジトリの各ブランチの最新版でのコンパイルを、オンラインで試して見れるサイト作ってる人がいた。

C#チームの公式提供じゃないし、まだまだ作業途中みたいですけども。

  • Lucian (C#チームの中の人)が、自分のリポジトリでasync任意戻り値の試験実装してる
  • ashmind (TryRoslyn作ってる人)が、そのLucianの個人リポジトリのブランチをTryRoslynに追加してくれた
  • Lucian、早速利用

みたいな感じになってた。

参照戻り値と参照ローカル変数

$
0
0

C# 7の説明、1つ足しました。参照戻り値がらみ。

参照戻り値と参照ローカル変数

追加される構文自体は割とシンプルなんですが、活用できそうな場面まで含めて説明しようとするとなかなか骨が折れる感じの機能。

まず、メモリ管理の方法について(スタックとかヒープとか)知ってないとピンとこないですしね。

「別の何かを参照する」って考え方も、そこそこ素養を求める概念ですし。 C言語とかC++で「ポインターは難しい」とか言われるのも、同種の問題だと思います。

ということで、GitHub上のディスカッションでも、大体は、

  • 活用場面がよくわからない
  • (自分は)使わなさそうなのに、複雑性を増すのには反対
  • 構造体は immutable に作れってのが常識じゃないのか

なんて話がまずあって、それに対して、

  • メモリ管理の手法とか知らない人はそう言って、パフォーマンスをいとも簡単に落とすんだ
  • パフォーマンスを求めると、mutable な構造体を配列で持っとくしかない場面があるんだ

とかの返事が毎度ついてる感じ。

文法自体についての反対意見はあんまりなさそう。しいて言うなら、

  • 非同期メソッドとかイテレーターとかでも使いたいけど、Task<ref T>とかIEnumerable<ref T>は作れないよね?
  • ローカル変数の宣言で、var (変数の型推論)を使う場合ですらref varって書かないといけないのはちょっと面倒

みたいな話が出てるくらい。

まあ、なかなか活用しどころが想像しにくい機能ではあるんですが、C# チーム的には優先度結構高いでしょうね。 Build Insiderの方で書きましたけど、 今、パフォーマンスに対する要求がかなり上がってるので。 .NET Core関連のチームとか、C#チーム自身とかにとってはかなり有用な機能のはず。 多くのプログラマーにとって直接使うことがない機能であっても、 低レイヤーなライブラリとかツールとかの性能向上が見込めるので、間接的な恩恵はそこそこありそうな気がします。

6/6 追記:

この手のメモリ管理がらみのパフォーマンス改善の話に付いて回るのは、ガベージコレクションもかなり高性能になってて、もうガベコレに任せてても大体大丈夫なんじゃないかという議題。

確かに、MS製ガベコレって結構高性能なんですよね。それでもガベコレ除けをきっちりするとかなりのパフォーマンス改善したりしますが。 仮にまあ、ガベコレがもっともっと優秀になったとしても…

その優秀なガベコレがどこででも使えると思うなよ!

と思うわけです。 ガベコレのコードなんて、.NETのものなんてファイルサイズが1.2MB(GitHubに"we can't show files"って言われるやつ)、行数3700行を超える長大なC++コードです。どこまで手書きでどこまで機械生成かわからないなんて話もありますが、どちらにしたって、なかなか保守が大変そうな分量。 特定の1環境で保守するのはまだ成り立つんですが、全然スペックの違う異なる環境向けにそれぞれ提供とかにあると、なかなか大変そう。 要するに何が言いたいかというと、あんまりこういうレイヤーの改善に期待してると、新しいプラットフォームに移りづらくなるとかのリスクもあったり。

具体的に、最近自分はUnityでiOS/Android両対応のゲームを作ってるわけですけども、 どうも、ヒープ確保の性能がiOSとAndroidでだいぶ違うみたいで、同じコードを書いててもAndroidでだけパフォーマンスが出なかったりします。 (他にもパフォーマンス ネックの原因になってそうな場所は多いんですが、ヒープ確保もネックの1つなことは間違いなさそう。)

一般論としても、「ムーアの法則での発展を期待していたら、モバイルな時代が来ちゃってむしろ時代が巻き戻った」なんて言葉よく聞くわけでして。 今更ながらC#に参照戻り値みたいな「使う人を選ぶ」機能が入るのも、そういう時代背景があるんじゃないかなと思います。

Viewing all 483 articles
Browse latest View live