小物エンジニアの会でオブザーバーパターンのアンチパターンについて発表してきた
小物エンジニア年収780万円以下だそうです
小物エンジニアの会 : ATND http://atnd.org/events/41091
発表資料は面倒くさかったのでGistです
hanabi.md https://gist.github.com/mizchi/6081622
西新宿のありふれた公園で酒飲みながら屋外発表会、破滅的でした
JavaScriptで型が書けるDSLを提供するdeftypes.js作った
こじらせJavaScriptシリーズです。
mizchi/deftypes.js https://github.com/mizchi/deftypes.js
主にcoffee-script用のDSLです。以下すべてcoffee。
ブラウザ
<script src="https://raw.github.com/mizchi/deftypes.js/master/deftypes.js"></script> Deftypes(); //provide DSL
Node
npm install deftypes
概要
型が書けます。残念ながら動的チェックです。
Point = {x: Number, y: Number} p1 = def Point, {x:1, y:2} #=> {x: 1, y:2} p2 = def Point, {x:1, z:2} #=> type error
defとTがDSLです。オプションで何もせずにインスタンスを返却するだけするモードもあります。これによってパフォーマンスを落とすことなく、型を明示的に宣言しながら開発することができます。(その際のオーバーヘッドは型情報の宣言のみで、ほぼ無視出来るでしょう)
Nullable型
NullableNumber = {n: T.Nullable(Number)} p1 = def NullableNumber, n:1 p2 = def NullableNumber, n:null
配列
number_list = def [Number], [1,2,3]
関数型
f1 = def T.Func([Number, Number], String), (m, n) -> "#{m}, #{n}" f1(1,2) #=> "1, 2" f1("",2) #=> argument error
引数と返り値の型を動的にチェックします。違反が検出されたら例外をthrowします。
型宣言されたインスタンスを変更するとき、専用の高階関数の中で副作用をだすようにすれば、高階関数を抜けた時にも型チェックをすることができます。
p = def Point, {x:1, y:2} def Point, p, -> @x = 3 # Type Error def Point, p, -> @y = "not number"
やや面倒ですが、副作用を出すという危険な行為は面倒臭くしておきたいのです。
これを無視してブロック外で行われた変更は検出しません。実装上は検出できるけど、このライブラリ専用の挙動が増えすぎるのでまだ避けてます。
それ以上の詳しくはREADMEとテストコードをみてください。
用途
静的解析ではないので、テストコードを書いたりしてカバレッジあげないとあまり意味がありません。むしろテストコードでの型チェックに使うといいかもしれません。
型をコード中に定義して文芸的プログラミングな文脈で可読性をあげる目的もあります。これは個人的な目的です。
1つの流儀を持つこと
流儀を知らないということは、何者にも縛られていない、ということではない。自分の癖に振り回されていることに、無自覚なだけだ。
ってのは、中学時代の部活の恩師の受け売りなんだけど、大人になるにつれ、特にインターネットを眺めるにつれ、無自覚に自分の癖に振り回されている人を見る機会が増えている気がする。
インターネットには反知性主義・反権威主義の皮を被った「怠惰の言い訳」があまりにも多い。
わかり易い例として、2chの哲学系のまとめを見るといいと思う。必ず導入かオチにキャッチーでわかりやすい反知性主義の言い訳があるはずだ。
それはまとめ人の程度を示しているだけとも言えるが、傾向として2chは反知性主義が支配している場であると思う。2chは嫌いではないけど相手の弁をそれによって封殺している流れをみると、僕はイライラする。で、はてブにもそういうのが増えてきた。
何かの視点を獲得することは、自分自身を捉えていた檻を自覚するようになることだ。檻を破壊するも、あるいは居心地の良い檻の中の生活を志向するにも、必ずその檻を自覚することからはじまる。
反知性主義の弁は、ほとんどの人の耳に心地よく、また伝搬しやすい。それを理解するのに必要なものは、なにもないからだ。なにも知らないでいいことの根拠になる。
何かに熱くなることはかっこわるい、みたいな風潮は、真摯に向き合っている人に対して失礼だと思う。専門性の獲得はそこからは生まれない。僕は誰もが何かに精通していて、お互いに何らかの価値を交換しあえたら楽しいなと思っているし、そうであってほしい。
プログラミングはそれ自体が目的であっていい
これ読んで思ったこと。
プログラミングを勉強したい人が勉強する前にすべきこと - もとまか日記 http://d.hatena.ne.jp/moto_maka/20130512/1368308092
僕がプログラミングをはじめたとき、何を思ってプログラミングをはじめたか思い出してみようとしたけど、よく思い出せなかった。
ただ漠然と感じていたのは、プログラミングは個人が現実的にこの世界に直接手を加えることができる手段の1つであり、それをやらないのは勿体無い、といったことだったと思う。たぶん。
というわけで、最初にやったのはFirefoxのユーザースクリプトを書くことだったし、それはそれでよい経験だった。なんとなくゲームとかウェブアプリとか作りてーなー、と思って色んなライブラリを動かすだけ動かして満足した。プログラミング覚えて初めて最初の一年で10以上の言語のHelloWorldだけやったと思う。その結果Unixの環境構築がうまくなった。
その後はひたすらいろんな言語のウェブフレームワークを触り、PythonとMongoDBで遊んでいた。グラフィック関係もやりたくなったのでJavaScriptのHTML5Canvasで迷路を書いて、A*のアルゴリズムで最短経路を解かせたりしていた。
自分が地力でそこに行き着くまでに覚えた環境構築、ライブラリごとの思想、言語の触り心地、出来上がったアプリの感触、そこに無駄だったものは何一つ無い。
半年でアプリが作れる!という謳い文句を僕は信じていない。そこに至る全てをオミットしているからだ。ちょっとパラダイムが変わると簡単にハマってしまうからだ。現実のアプリを作るレベルで、最短経路の知識で済むこと絶対に無い。
大事なのは、いくつ地雷を踏んだか、だ。地雷を踏んだ数だけ強く慣れる。真に必要なのは、独力での問題解決能力。Python2系でsjisのHTMLをlxmlでスクレーピングすると、地雷を7つぐらい同時に踏めるからおすすめだ。
話題になった技術は概要を読むだけでなく、自分の手で動かすことが大事だと思っている。サンプルを少しづつ変更して、この技術は、何を許して何を許さないかを知ること。それが欠けたプログラミング技術は、ネタなしの寿司である。
プラグマティズムと理想
これは業務としてプログラミングをするようになって気づいたんだけど、「動けばいい」というだけの指針で設計されたコードは、ほとんどにおいて糞コードである。
たとえばリファクターを嫌う創業者が、動けばいいというマインドを共有した技術者だけを集めて書かせたコードは、往々にして破綻する。(この業界で一番よくあるパターンだ)
「動けばいい」はプロジェクト初動においてはものすごいベロシティを発揮するが、それを継続するのは至難の技だ。そしてそれを難しいと伝えることは難しい。人は経験からしか学べず、しかもより直近の経験から学ぶから、直近の見た目上のベロシティにバイアスが引っ張られる。コードが書けない人はなおさらだ。
このようなことを起こさないために、そこで必要になるのはある種の言語マニアのような人の存在だと思っている。数万行のコードベース、大規模なアーキテクチャを成立させるためのスキルは、偏執的なデザインパターンや設計に対する執着、言語仕様に対する深い理解から生まれると僕は思っている。(さらに言うと仕様理解度もだが、ここでは割愛する
モデルとビューの分離の指針、デザインパターンの準拠、インスタンスを握るスコープの最小化や、組み込みメソッドによるコードの単純化、そういうのにこだわりを持つ人のレビューがあって、はじめてまともなコードが成立する。継承地獄やシングルトンという名のグローバル変数が検知されず、使用しているライブラリのデザインパターンを無知ゆえに独自の解釈でねじ曲げた場合、糞コード一直線だろう。
僕がよく個人的によくやるリファクタリングは、糞コードに至るプログラムのフローだけ整えておいて、どうしようもなく出来上がった糞コードを一箇所に押し込める。「副作用が0」もしくは「副作用しか無い」ようなメソッドに抽出しておく。その際はメソッド名で、副作用があるかないかわかりやすくしておく。
ここのリファクタリングは、思いついたらやる。だいたい他の箇所のコード書いてるとこう書けばよかったんだって気づく。
言語にしか興味が無い人
たとえば、Rubyist達はRubyで書くこと自体を目的にしているケースをよくみる。一般的に、コミュニティが小さい言語ほどコードの質は高い。美しいコードに囲まれて生活するということは、それだけが彼らの転職目的になりえるわけだ(Rubyを書きたいから転職、もこの業界でよくみるものの1つだ。
プログラミング自体を目的にした人達は、基本的にHaskellかLispの関数型言語に手を出す印象がある。それはもちろん小さいコミュニティで、コードの品質が高く、言語そのものに対する研究に興味がむくからだろう。
僕もまあそれなりに手を出しているのだけど、他の人も抑えるべきだと思った概念は、次のものだ。
- Haskellにおける入出力IOと副作用の概念
- HaskellのMaybe, またはScalaのOption型
- Scalaのtrait
- Node.jsの非同期Promiseパターン
- C#のgetter/setter/readonly/async等の型アノテーション
それほど敷居が高くないのを選んだので(Haskellの非同期IOはちょっときついが)、興味がある人は調べるといいと思う。
最後に
この記事は昼間からLeague of Legends を飲酒プレーしながらはてブ眺めてたら意識が高まりウッってなったので書いた
最近買った本
- 作者: ブラッドレー・ボンド,フィリップ・N・モーゼズ,わらいなく,本兌有,杉ライカ
- 出版社/メーカー: KADOKAWA/エンターブレイン
- 発売日: 2012/09/29
- メディア: 単行本
- 購入: 40人 クリック: 2,071回
- この商品を含むブログ (86件) を見る
- 作者: ジョージ・R・R・マーティン,目黒詔子,岡部 宏之
- 出版社/メーカー: 早川書房
- 発売日: 2012/03/31
- メディア: 文庫
- 購入: 2人 クリック: 64回
- この商品を含むブログ (35件) を見る
- 作者: 月村了衛
- 出版社/メーカー: 早川書房
- 発売日: 2010/03/19
- メディア: 文庫
- 購入: 3人 クリック: 77回
- この商品を含むブログ (66件) を見る
言語実装パターン ―コンパイラ技術によるテキスト処理から言語実装まで
- 作者: Terence Parr,中田育男,伊藤真浩
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/12/24
- メディア: 大型本
- 購入: 5人 クリック: 333回
- この商品を含むブログ (13件) を見る
コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus)
- 作者: 西尾泰和
- 出版社/メーカー: 技術評論社
- 発売日: 2013/04/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (37件) を見る
- 作者: Benjamin C. Pierce,住井英二郎,遠藤侑介,酒井政裕,今井敬吾,黒木裕介,今井宜洋,才川隆文,今井健男
- 出版社/メーカー: オーム社
- 発売日: 2013/03/26
- メディア: 単行本(ソフトカバー)
- クリック: 68回
- この商品を含むブログ (11件) を見る
- 作者: M.D. ConradBarski,Conrad Barski,川合史朗
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/02/23
- メディア: 大型本
- 購入: 1人 クリック: 18回
- この商品を含むブログ (19件) を見る
JavaScriptでDIできる Injector.js つくった
仕事でRobotlegsというAS3のフレームワークを使っているのだけど、DI機構がかっこよかったので、Injectorだけ真似て作ってみた。
mizchi/injector.js · GitHub https://github.com/mizchi/injector.js
Robotlegs AS3 Micro-Architecture - Home http://www.robotlegs.org/
使い方
ConstructorClass.inject に {key:InjectedClass} で実体化するインスタンス名と実体化するクラスを登録する。
CoffeeScriptで違和感無いような記法でチューニングしてある。
class UserModel class X_View Injector.register(@) @inject: model: UserModel Injector.mapSingleton UserModel, new UserModel x = new X_View console.log x.model
JSだとこうなる
function UserModel(){}; function X_View(){}; X_View.inject = { model:UserModel } Injector.register(X_View); Injector.mapSingleton(UserModel, new UserModel); var x = new X_View; console.log(x.model);
JSだとあんまりかっこよくないですね…
子のInjectorも作れる
childInjector = new Injector()
他、明示的に呼ぶ必要があるが、Injector.ensureProperties(hoge)を使えば、hogeがHogeプロトタイプに登録されたすべてのinject対象をみたしていることを確認できる(そうでない場合は例外を吐く)
詳細はREADMEにて。bower にも登録したので bower install injectorでもいい。node.jsでもnpm installすれば使えるんじゃないかな。(使いたいかはともかく)
仕組み
Injector.mapSingletonでは、Injector.register(Hoge) でHogeクラスのprototypeに登録している。
Injector.mapValueでは、インスタンスごとにgetterで返すクラスをシングルトン化して、実体を this._...に保存している。
現時点での欠点として、mapValueはそのプロパティを最初に参照した時の遅延評価になってしまう。インスタンスをInjectorに通知したり、Injectされる専用のコンストラクタ処理を持つクラスを用意したくなかったので、このような形になった。
思想
mapValueはどちらかというとオマケで、mapSingletonが主役。
DIを使ってUIを構築してきた経験上、Viewはリスト構造以外ほとんどシングルトンであり、DIがない環境だとシングルトンやグローバル変数で取得せざるを得なくなり、どこから取得されているかわからなくなる。これはコードをスパゲティ化させる要因になりうる。
そのクラス内の名前空間において、injectされるインスタンスその場所を明示的に設定すると、見通しがよくなる。
だいたいregisterするのはそのクラスの宣言の中だが、map するのはメインの処理がはじまって以降なので、動的にinjectすることはあまり想定していない。そのようなケースは既に破綻している。
酷使するとメモリが若干程度は漏れそうな気がするが、パフォーマンスセンシティブな箇所よりはアーキテクチャを破綻させないようピンポイントで使うといいと思う。サンプルにUserModelとか書いているのは、もっともシングルトン化されそうなクラスだから。
いろいろ粗いので PullRequestください。以上。
Web系新卒っていうかゲーム開発者一年目が去年読んだ技術書 & ライブラリ
カタ氏(@hotchemi)が意識高い記事書いてたので、自分もまとめてみる。
文系学部生がSIerに入社してから読んだ本メモ - ギークに憧れて http://hotchemi.hateblo.jp/entry/2013/04/01/000844
自分Web系っていうかHTML5+Unity+AS3 のゲームガッツリ系+Webもやるって感じなので、最近の自己認識としてWebっていうよりはゲームプログラマな気がしている。
JSが多いのはHTML5ゲームの技術調査とかしてたからです。
書籍
- 作者: Bruce A. Tate,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2011/07/23
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 230回
- この商品を含むブログ (65件) を見る
- 作者: Miran Lipovača,田中英行,村主崇行
- 出版社/メーカー: オーム社
- 発売日: 2012/05/23
- メディア: 単行本(ソフトカバー)
- 購入: 25人 クリック: 580回
- この商品を含むブログ (73件) を見る
正確には、会社で最初のプロジェクトでHaskellを部分的に使ったため、これの原著の方を必死こいて読んでた。
Haskellをやると副作用についての考え方が変わる。今までの触ってきた言語がいかに危険なことをやれていたかわかって、胃が痛くなる。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (140件) を見る
胃が痛くならないようになりたい。
とくにコメントについての章は賛否あるが一読して自分の中で考える余地を持っておくことを薦める。
- 作者: 濱野純(Junio C Hamano)
- 出版社/メーカー: 秀和システム
- 発売日: 2009/09/24
- メディア: 単行本
- 購入: 31人 クリック: 736回
- この商品を含むブログ (155件) を見る
JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
- 作者: Douglas Crockford,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/12/22
- メディア: 大型本
- 購入: 94人 クリック: 1,643回
- この商品を含むブログ (190件) を見る
- 作者: Nicholas C. Zakas,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/03/20
- メディア: 大型本
- 購入: 9人 クリック: 1,176回
- この商品を含むブログ (33件) を見る
ステートフルJavaScript ―MVCアーキテクチャに基づくWebアプリケーションの状態管理
- 作者: Alex MacCaw,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/09
- メディア: 大型本
- 購入: 7人 クリック: 356回
- この商品を含むブログ (11件) を見る
JavaScriptパターン ―優れたアプリケーションのための作法
- 作者: Stoyan Stefanov,豊福剛
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/16
- メディア: 大型本
- 購入: 22人 クリック: 907回
- この商品を含むブログ (76件) を見る
Unity入門 ~高機能ゲームエンジンによるマルチプラットフォーム開発~
- 作者: 高橋啓治郎
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2011/10/01
- メディア: 大型本
- 購入: 15人 クリック: 609回
- この商品を含むブログ (24件) を見る
ActionScript Developer's Guide to Robotlegs: Building Flexible Rich Internet Applications
- 作者: Joel Hooks,Stray (Lindsey Fallow)
- 出版社/メーカー: O'Reilly Media
- 発売日: 2011/08/20
- メディア: ペーパーバック
- クリック: 1回
- この商品を含むブログを見る
- 作者: ケイティ・サレン,エリック・ジマーマン,山本貴光
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2011/01/29
- メディア: 単行本
- 購入: 10人 クリック: 92回
- この商品を含むブログ (65件) を見る
ゲームのコアのメカニクス、メカニクスの上に生まれるゲーム性、そしてユーザーの背後にある文化をからめて考察する章がとてもよかった。下巻が未翻訳で出そうにないのが辛い。
読んだコード
あくまで「使った」、ではなく、「読んだ」。でもヘヴィに使うライブラリを必然的に読んでた感じ。
wise9/enchant.js · GitHub https://github.com/wise9/enchant.js
HTML5ゲームフレームワーク。イベントディスパッチやアセットのロード周りは参考にさせてもらった。
documentcloud/backbone · GitHub https://github.com/documentcloud/backbone
JSのMVCフレームワーク。オブザーバーの実装とViewのイベントバインディングが渋い。
documentcloud/underscore · GitHub https://github.com/documentcloud/underscore
関数型的な関数群。関数型言語を知ってるとすごい楽しく読める。最近だったら軽量版のlodash読むほうがいいらしい。
jquery/jquery · GitHub https://github.com/jquery/jquery
ふざけんなと思いながらJSの黒歴史を知ることになる。正直キレそうになるコードが多々あるが、歴史の重みを感じるとしょうがなくも感じる。綺麗な実装読みたけりゃzeptoだったのでは、とr7kamura に言われた。そうかも。
fastladder/fastladder · GitHub https://github.com/fastladder/fastladder
Livedoor ReaderのOSS実装。絶賛リファクタリング中。polyfillが大量でmalaさんのテクニックと思考を追う感じになってる。
jashkenas/coffee-script · GitHub https://github.com/jashkenas/coffee-script
ご存知CoffeeScript。パーサジェネレータからAST、構文木から意味解析でノード実装とクロージャ判定の実装までだいたい読みきった。辛いのでもっとモダンな実装(CoffeeScriptRedux)読むといいとおもう。src/rewriter.coffeeの関数適用パターンマッチに暗黒面を感じた。
たぶん自分は Jeremy Ashkenas 信者なんじゃないかなっていうのは感じる。(coffee, underscore, backbone)