ゆるふわで雑な日記

Microsoft系の技術情報を中心にゆるふわに綴っていく予定です

感想とか

CodeRetreat@名古屋ギークバーに参加したお話

※ イベントの詳細は、タイトル兼リンク先のサイトを参照ください。

CodeRetreatとは

趣旨をすべて吹っ飛ばして、やることだけを説明するならば、
45分1セットのペアプロを何回か回して勉強するという感じ。

課題として、45分間で、Conway's Game of Life (以下ライフゲーム)を1から実装する簡単なお仕事です。
特徴としては、毎回コードを削除して、必ず1から実装する必要があることと、
(強制ではないものの)多少(TDDをするとか、if禁止とか)の制約をつけたりされる感じです。

今回は、純粋な参加者ではなく、ファシリテーター側のサポートをした感じです。
というわけで、純粋に自分が参加して、実際に手を動かしてどうだったとか、特に何もないわけですが、
全体を俯瞰でみた感想的な物を少し書いてみます。

みんな始めから色々難しく考えすぎでは?

はじめに断っておくと、若干遅刻したので開始時間にはいませんでした。
到着時に情報共有されたこととしては、
1. ペアプロに慣れている参加者は少ない。 1. ライフゲームを詳しく知っている参加者は少ない。

という感じらしい。
となると、まず始めは愚直でいいからとりあえず動くようにしてみる感じでアプローチすると良さそうな気がしますね?
ところがそうでもないらしい…
なんか、綺麗な設計して~、素敵なコード書いて~。みたいな人が多かった?
ライフゲーム自体は(どう実装するのかは置いておくとして)、
1. 【世界】の「今の状態」を取得できる 1. 【世界】が「次の状態」に遷移できる

が出来れば良いだけでなんですよね?
もう少し具体的にすると(世界を単純な2次元座標の集合だと定義すると)
1. 任意の座標の次の状態を判定する 1. 任意の座標に隣接する「生存」している「セル」を数える 1. すべての座標の状態を取得できる

だけできれば何とかなるんです。

(最初段階であたりをつけるのも悪いことではないと思いますが)どう表示するか?とかはその後考えれば良いんですよ。

とはいえ

「今日」うまくいかなかったなら、明日(以降)できるようになればいいので、
「それはそれ」的な割り切りも大切です。
(ごく一部の例外は(どんな事にも)ありますが)みんな最初はできないのです。
という事で、本日参加した方は、これで終わりではないのでこれからもやっていきましょう。
何となく興味を持った方は雑に@Dominion525宛にメンション飛ばしましょう!
色々調整がつけば開催されます。

まとめ

CodeRetreat良い取り組みなのでみんな参加するといいと思います。

Re:Microsoft MVP for Developer Technologiesを受賞しました。

TwitterやFacebookですでにお祝いのコメント等いただいているので、
ご存知の方もいらっしゃるとは思いますが、
本年もMicrosoft MVPを受賞しました。
詳しく知りたい方や、応募を検討されている場合は、
こちら(Microsoft MVP Award)のページを参照してみてください。

正直、昨年受賞したときは、
「来年はないな」と思ったりしましたが、 何とか今年も受賞することができました。 登壇する機会を与えていただいたイベント主催者の方や 参加者の方々等たくさんの方に支えていただいたお陰です。
更に1年MVPとして活動する機会を得ることができたので、
少しでも「誰か」の「何か」を提供できればと思っています。

↓ 一応昨年のエントリーも晒しておきます。
blog.relucer.net

IEnumerable<T>がnullまたはの要素の数が0個の場合を判定して処理を分岐したいときの話

どうしてますか?
って単純な疑問を提示するだけのエントリー

例えば、こんなやつ(Any()の結果を反転するパターン)

void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if(!(foo?.Any() ?? false))
        Initialize();

    DoSometing();
} 

!とか出来たら使いたくない

例えば、こんなやつ2(Allするパターン)

void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if(foo?.All(_ => false) ?? true)
        Initialize();

    DoSometing();
}

空集合に対するAllが必ずtrueなことを知らないと戸惑う + 直感的じゃない

例えば、こんなやつ3(数えたらいいじゃん)

void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if((foo?.Count() ?? 0) == 0) return;
        Initialize();

    DoSometing();
}

…無限のIEnumerableの時やばいね?

例えば、こんなやつ4(else使おうよ)

void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if(foo?.Any() ?? false) 
    {
        DoSometing();
    }
    else
    {
        Initialize();
        DoSometing();
    }

}

…DoSometing();2回書いてる

例えば、こんなやつ4(else使おうよ2)

void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if(foo?.Any() ?? false) 
    {
    }
    else
    {
        Initialize();
        DoSometing();
    }

}

…ifで実行されるの空じゃん

例えば、こんなやつ4(それっぽいメソッド作る)

sstatic class Extensions
{
    internal static bool IsNullOrEmpty<T>(this IEnumerable<T> target)
                                       =>  foo?.All(_ => false) ?? true;
}
void Hoge<T>(IEnumetable<T> foo)
{
    // fooがnullまたは空の時
    if(foo.IsNullOrEmpty()) 
        Initialize();

    DoSometing();
}

空集合に対するAllが必ずtrueなことを知らないと戸惑うけど名前付いた

他にもあるかもですが、どれが好きですか?
個人的には(たくさん書くなら)最後のやつかな

細かなお話

先日Twitterで、

Func<int,int> f = bool ? x => x + 1 : x => x -1;

Build できない的な話をしたりしました。 上のコードが Build できないのは、
x => x + 1x => x -1 の間に暗黙の変換がないからなんですが、 x => x + 1 単体でも型は不明(Action<T>なのか、Func<T,RT>なのかは人が見てもわからないしユーザー定義の delegateを含めると可能性は無限大)

いや、左に型書いてあるじゃんって思いますよね?
C#的には左辺の型を右辺に適用することは基本的にありません(でした)。

// そう、こいつが現れるまでは!!
int i = default;

まあ奴は 0 をセットしているだけなので構文解析的なコストはないのでやりやすい ってことで色々やってみた
C#

VB

scala

なるほど?C#もっと色々使って推論したら良いのにっていう人の気持ちもわかるし、
構文解析のコストが~っていう人の気持ちもわかる
(型推論とか禁止なって人の気持ちはあまりわからない) まあ、このケースに対して何か変化があるかどうかは知らないけど、C#の将来のバージョンアップ(8.0くらい?)で左辺型推論入るらしいよ?