@thorikiriのてょりっき

@thorikiriがWebとかAndroidとかの技術ネタや本を読んだブログです

東京Node学園 8時限目 #tng8 に行ってきました

と言うことで、メモを投下。

Param Tuner

資料 → ParamTuner 東京Node学園#8
しばらく中に入れなくて、聞けてませんでした。
統計解析の話だったようです。資料見て自習します。

  • QA
    • JavaScriptで統計解析やるにあたってデータの量とかはどうなんですか?
      • 実際にはHadoopで裏でやっていますが、その前段階の傾向を見るのに使っています
      • なので、そんなにデータは多くはないです。

Nodeとプロミスと時々、関数型

資料 → Node, Promises and Functional Programming // Speaker Deck

  • ことの経緯
  • 非同期処理を書く時に何を考えるのか?
    • タスク同士の依存関係を考える
    • 必要な操作の順序を考える
    • 最後に、その制御フローを考える
  • コールバック VS プロミス
    • コールバックの良くないところ
      • 処理をモジュール化したり組み立てたりするのが難しい
      • 逐次処理か並列処理かを明示的に制御する必要がある。
      • あと、ネストが深くなってしまう問題があるけど、重要な論点ではない。
    • 複数のファイルを並列的にfs.statしてmtimeを取り出す処理
    • 複数ファイル全ての結果が揃ったら次の処理を行う
    • この実装をした後に、追加の処理を入れたいとする
      • 1つ目のファイルからサイズを取り出したい処理を追加
    • 単純に追加すると、ファイルに2度アクセスすることになり効率が悪くなる
    • 正しい順序で、効率良く処理させると、実装がかなり複雑になる
    • 結果
      • 正しくコードを書くのが大変
      • 設計の意図が明確にならないので、メンテナンスが大変
      • 逐次処理か並列処理かで、後続の処理を実装する方法が変わってしまう
  • プロミスとは
    • 完了していないかもしれない計算の結果が入っている箱
    • プロミス自体も値なので、関数の間で受け渡しが出来る
    • 計算が完了すると特定の処理を呼び出したりする(ものが多い)
  • しかしながら
    • 必ずしも全てのプロミスが関数型ではない
    • 言語やライブラリによって異なる
  • 関数型とは?
    • あらゆるものを値として扱うことで問題を解く手法
    • 命令型はHowを記述して伝える
    • 関数型はWhatを値同士の関係によって記述して伝える
      • 関数は、値同士の依存関係を定義するもの
    • 関数は、引数を得て、戻り値を返す
      • 複数の関数を合成して、大きな関数にする
      • 別の関数への入力として、パイプラインを作る。
  • 関数型プログラミング
    • あらゆるものを値として扱い、
    • 値同士の依存関係を関数で表現し、
    • 複数の関数を合成してより大きな関数を作る
  • 先の例で言うと
    • 複数の非同期計算を合成して大きな計算をする
    • 後で処理を追加したいときには
      • thenを使う
      • thenは、プロミスに依存する別の非同期処理を記述する
      • thenで記述された処理は、値がいつ利用可能になり、どんな順番で処理するかを気にする必要がない
  • プロミスとthenを使うと
    • 記述された依存関係を元に実行順序を自動的に解決するので、
    • 依存関係でプログラミング出来る
  • 結果を待ちたい場合
    • プロミスの配列をリストに対するプロミスにする
    • これによって待合せが表現できる
  • 課題に戻って
    • プロミスを使うと、必要な操作の順序を考えなくても良い
    • なので、非常にシンプルにプログラミングが出来る
  • プロミスは難しい
    • 先のブログに対する反論記事
    • プロミスを使うと
      • thenやlistで意味的に隠蔽してしまうので、認知的コストが大きい
      • プロミスを使ったものは、学習コストがかかる
  • 反論に対する反論
    • 簡単であるかよりも、シンプルであるかを問うべき
    • やりたいことが変わった時に、コードの変更が少なくて済む
  • 結局
    • どちらもただしいと思う
    • コストとメリットを天秤にかける
      • ただ、非同期プログラミングのコストの支払期限は意外と早いのでは?
  • まとめ
    • コールバックはとっつきやすい
    • 変更に強くするならプロミス
  • メッセージ
@koichik さんから
  • 3年ほど前はnode.jsでもプロミスを使っていました
  • しかしながら、あんまり評判が良くなかったようです。
  • プロミスが嫌われていたのは、プロミス自身ではなくて、JavaScriptでのプロミス自身がいけていなかったから。
  • 先の例で言うと、実際にはエラー処理をしなければならないが記述されていない
  • エラー処理を実装すると、結局冗長にせざるを得ない
  • 現在、node.jsではメカニズムとして一番シンプルなコールバックのみ提供している
  • プロミスの実装は、別のモジュールで色々な人が作っている
  • node.jsのスタンスとしては、モジュールとして好きなものを作っていいよということが現在のスタンス

LT

LET IT CRASH!?

資料 → 東京Node学園#8 Let It Crash!?

  • Let It Crash?
  • 堅牢なコードを書くには?
    • ディフェンシブプログラミング
      • 失敗する可能性があるものは失敗するので、失敗に備えておこう
      • 引数などはチェック、例外を捕まえる
      • アプリがエラーから回復する
      • 通常処理とエラー処理が混在する
    • Let it crash
      • 失敗に備えない
      • 例外を捕まえないで、スーパーバイザがエラーから回復する
      • 通常の処理と分離出来る
  • スーパーバイザ
    • 1つクラッシュすれば、それだけリトライ。One4One
    • 1つクラッシュすれば、関連を全てリトライ。All4One
  • You! さっさとクラッシュしちゃいなよ!
    • process.on('uncaughtException')
      • OnErrorResumeNextとは違うのですよ。
    • domain.on('error')
      • エラーを無視するな
      • エラーが起きたら、プロセスをシャットダウンしなさい

といった所でLTタイム終了しちゃいましたが、まだ半分までです。
domainのAPIドキュメントを見てね!

LT2 Object.defineProperty

資料 → 不明

  • Object.defineProperty
var obj = {};
Object.defineProperty(obj, 'prop', {
    // ここにプロパティのオプションを書く
});
  • オプション
    • configure
      • falseを設定すると、上書きとか削除とかできなくする
    • enumerable
      • for inのループで出てこなくなる
    • wraitable
      • 上書きできなくなる。
      • 定数とか。厳密には定数とは違う。現状のJavaScriptで実現出来る方法。
    • get, set
      • getter / setter が定義が出来る
  • 複数のプロパティをまとめて定義することも可能
Object.defineProperty(obj, {
    'prop1': {
         // オプション
    },
    'prop2': {
        // オプション
    }
})

サーバサイドJavaScript Node.js入門

サーバサイドJavaScript Node.js入門