SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
Immutable @ JavaScript
var	
  me	
  =	
  {	
  
	
  	
  name:	
  	
  	
  "Yuta	
  Shimakawa",	
  
	
  	
  tw:	
  	
  	
  	
  	
  "@banana_umai",	
  
	
  	
  qiita:	
  	
  "bananaumai",	
  
	
  	
  github:	
  "bananaumai"	
  
};
ではございません
at a glance...
不変データ
Seq
List
Map
OrderedMap
Set
OrderedSet
Record
var	
  list1	
  =	
  Immutable.List.of(1,	
  2);	
  
var	
  list2	
  =	
  list1.push(3,	
  4,	
  5);	
  
var	
  list3	
  =	
  list2.unshift(0);	
  
var	
  list4	
  =	
  list1.concat(list2,	
  list3);	
  
assert(list1.size	
  ===	
  2);	
  
assert(list2.size	
  ===	
  5);	
  
assert(list3.size	
  ===	
  6);	
  
assert(list4.size	
  ===	
  13);	
  
assert(list4.get(0)	
  ===	
  1);	
  
https://github.com/facebook/immutable-js/
JSオブジェクトとの
相互変換
var	
  map1	
  =	
  Immutable.Map({a:1,	
  b:2,	
  c:3,	
  d:4});	
  
var	
  map2	
  =	
  Immutable.Map({c:10,	
  a:20,	
  t:30});	
  
var	
  obj	
  =	
  {d:100,	
  o:200,	
  g:300};	
  
var	
  map3	
  =	
  map1.merge(map2,	
  obj);	
  
//	
  Map	
  {	
  a:	
  20,	
  b:	
  2,	
  c:	
  10,	
  d:	
  100,	
  t:	
  30,	
  o:	
  200,	
  g:	
  300	
  }
https://github.com/facebook/immutable-js/
var	
  deep	
  = Immutable.Map(	
  
{	
  a:	
  1,	
  b:	
  2,	
  c:	
  Immutable.List.of(3,	
  4,	
  5)	
  });	
  
deep.toObject()	
  //	
  {	
  a:	
  1,	
  b:	
  2,	
  c:	
  List	
  [	
  3,	
  4,	
  5	
  ]	
  }	
  
deep.toArray()	
  //	
  [	
  1,	
  2,	
  List	
  [	
  3,	
  4,	
  5	
  ]	
  ]	
  
deep.toJS()	
  //	
  {	
  a:	
  1,	
  b:	
  2,	
  c:	
  [	
  3,	
  4,	
  5	
  ]	
  }	
  
JSON.stringify(deep)	
  //	
  '{"a":1,"b":2,"c":[3,4,5]}'
入れ子データ
var	
  nested	
  =	
  Immutable.fromJS({a:{b:{c:[3,4,5]}}});	
  
//	
  Map	
  {	
  a:	
  Map	
  {	
  b:	
  Map	
  {	
  c:	
  List	
  [	
  3,	
  4,	
  5	
  ]	
  }	
  }	
  }	
  
var	
  nested2	
  =	
  nested.mergeDeep({a:{b:{d:6}}});	
  
//	
  Map	
  {	
  a:	
  Map	
  {	
  b:	
  Map	
  {	
  c:	
  List	
  [	
  3,	
  4,	
  5	
  ],	
  d:	
  6	
  }	
  }	
  }	
  
var	
  nested3	
  =	
  
nested2.updateIn(['a',	
  'b',	
  'd'],	
  value	
  =>	
  value	
  +	
  1);	
  
//	
  Map	
  {	
  a:	
  Map	
  {	
  b:	
  Map	
  {	
  c:	
  List	
  [	
  3,	
  4,	
  5	
  ],	
  d:	
  7	
  }	
  }	
  }	
  
var	
  nested4	
  	
  
=	
  nested3.updateIn(['a',	
  'b',	
  'c'],	
  list	
  =>	
  list.push(6));	
  
//	
  Map	
  {	
  a:	
  Map	
  {	
  b:	
  Map	
  {	
  c:	
  List	
  [	
  3,	
  4,	
  5,	
  6	
  ],	
  d:	
  7	
  }	
  }	
  }
https://github.com/facebook/immutable-js/
遅延評価(Seq)
var	
  oddSquares	
  =	
  Immutable.Seq.of(1,2,3,4,5,6,7,8)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .filter(x	
  =>	
  x	
  %	
  2)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .map(x	
  =>	
  x	
  *	
  x);	
  //	
  not	
  computed	
  here!	
  
	
  	
  
oddSquares.get(1);	
  //	
  9
https://github.com/facebook/immutable-js/
同等性
var	
  map1	
  =	
  Immutable.Map({a:1,	
  b:1,	
  c:1});	
  
var	
  map2	
  =	
  Immutable.Map({a:1,	
  b:1,	
  c:1});	
  
assert(map1	
  !==	
  map2);	
  
assert(Immutable.is(map1,	
  map2)	
  ===	
  true);
https://github.com/facebook/immutable-js/
JSで不変データ
Immutableなリストを
素朴に実装してみた
cloneによる実装
var	
  _	
  =	
  require('lodash');	
  
	
  	
  
function	
  iPush(arr,	
  val)	
  {	
  
	
  	
  var	
  arr2	
  =	
  _.clone(arr);	
  
	
  	
  arr2.push(val);	
  
	
  	
  return	
  arr2;	
  
}	
  
	
  	
  
var	
  arr	
  =	
  [];	
  
for	
  (var	
  i	
  =	
  0;	
  i	
  <	
  100000;	
  i++)	
  {	
  
	
  	
  arr	
  =	
  iPush(arr,	
  i);	
  
}
https://gist.github.com/bananaumai/cc2f4d90662aa823ce9e
…は
cloneのコストが膨大
Linked Listを実装
var	
  LinkedList	
  =	
  {};	
  
LinkedList.prototype	
  =	
  {	
  
	
  	
  head:	
  function()	
  {	
  
	
  	
  	
  	
  return	
  this._head;	
  
	
  	
  },	
  
	
  	
  
	
  	
  tail:	
  function()	
  {	
  
	
  	
  	
  	
  return	
  this._tail;	
  
	
  	
  },	
  
	
  	
  
	
  	
  push:	
  function(val)	
  {	
  
	
  	
  	
  	
  return	
  new	
  NonEmptyList(val,	
  this);	
  
	
  	
  },	
  
	
  	
  
	
  	
  forEach:	
  function(fnc)	
  {	
  
	
  	
  	
  	
  fnc(this._head);	
  
	
  	
  	
  	
  if	
  (this._tail	
  instanceof	
  NonEmptyList)	
  {	
  
	
  	
  	
  	
  	
  	
  this._tail.forEach(fnc);	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
};	
  
var	
  EmptyList	
  =	
  function()	
  {	
  
	
  	
  this._head	
  =	
  null;	
  
	
  	
  this._tail	
  =	
  null;	
  
};	
  
EmptyList.prototype	
  =	
  Object.create(LinkedList.prototype);	
  
EmptyList.prototype.constructor	
  =	
  EmptyList;
https://gist.github.com/bananaumai/164b24b264e0f917007c
var	
  NonEmptyList	
  =	
  function(head,	
  tail)	
  {	
  
	
  	
  this._head	
  =	
  head;	
  
	
  	
  this._tail	
  =	
  tail;	
  
};	
  
NonEmptyList.prototype	
  =	
  
Object.create(LinkedList.prototype);	
  
NonEmptyList.prototype.constructor	
  =	
  NonEmptyList;	
  	
  
LinkedList.of	
  =	
  function()	
  {	
  
	
  	
  var	
  _create	
  =	
  function(vals,	
  list)	
  {	
  
	
  	
  	
  	
  if	
  (vals.length	
  ===	
  0)	
  return	
  list;	
  
	
  	
  	
  	
  var	
  head	
  =	
  vals.shift();	
  
	
  	
  	
  	
  return	
  _create(vals,	
  new	
  NonEmptyList(head,	
  list))	
  
	
  	
  };	
  
	
  	
  
	
  	
  return	
  _create(	
  
	
  	
  	
  	
  Array.prototype.slice.call(arguments).reverse(),	
  
	
  	
  	
  	
  new	
  EmptyList()	
  
	
  	
  );	
  
};
var	
  list	
  =	
  LinkedList.of();	
  
for	
  (var	
  i	
  =	
  0;	
  i	
  <	
  100000;	
  i++)	
  {	
  
	
  	
  list	
  =	
  list.push(i);	
  
}	
  
https://gist.github.com/bananaumai/164b24b264e0f917007c
…は
(&pushはそれなりに速いけど・・・)
末尾再帰最適化
されないので難しい
(&Object.ArrayのAPIの実現しようとすると・・・)
immutable-jsのアプローチ
Trie
http://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%82%A4%E6%9C%A8
(def	
  list	
  [0	
  1	
  2	
  3	
  4	
  5])
ClojureやScalaが採用
しているアプローチ
Immutable.Listの実装
文字列のキーの代わりに
添字の数値をbitに変換、
パーティショニング
var	
  list	
  =	
  Immutable.List.of(1,…,1000);	
  
list.get(887);
http://hypirion.com/musings/understanding-persistent-vector-pt-2#f1n
実際は5bitずつ分割するので
↓
O(Log32N)
実際は32通り
http://hypirion.com/musings/understanding-persistent-vector-pt-1
var	
  list1	
  =	
  Immutable.List.of(1,2,3,4,5,6,7,8);	
  
var	
  list2	
  =	
  list1.set(5,	
  "beef");
list1 list2
http://hypirion.com/musings/understanding-persistent-vector-pt-1
要素のpush
var	
  list1	
  =	
  Immutable.List.of(…);	
  
var	
  list2	
  =	
  list.push(…);
最右のリーフノードに空きがある場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
最右のリーフノードに空きがない場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
rootから伸びるすべてのリーフが埋まっている場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
要素のpop
var	
  list1	
  =	
  Immutable.List.of(…);	
  
var	
  list2	
  =	
  list.pop();
最右のリーフノードが2つ以上の要素を持つ場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
最右のリーフノードが1つの要素を持つ場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
削除後rootノードが1つの要素だけをもつ場合
http://hypirion.com/musings/understanding-persistent-vector-pt-1
簡単なまとめ
Trieによるリストの表現
O(Log32N)のアクセス
最小限のコピー

Weitere ähnliche Inhalte

Was ist angesagt?

ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)Suguru Hamazaki
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみたAtsushi Kanehara
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」Nagi Teramo
 
R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装__nakamichi__
 
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoGrails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoTsuyoshi Yamamoto
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 

Was ist angesagt? (8)

ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)
 
篠崎Lt20141215
篠崎Lt20141215篠崎Lt20141215
篠崎Lt20141215
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみた
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
 
R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装
 
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in TokyoGrails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
fanscala1 2 scalaの基本
fanscala1 2 scalaの基本fanscala1 2 scalaの基本
fanscala1 2 scalaの基本
 

Andere mochten auch

型についてあれこれ
型についてあれこれ型についてあれこれ
型についてあれこれYuta Shimakawa
 
Web workers&parallel.js html5勉強会lt大会
Web workers&parallel.js   html5勉強会lt大会Web workers&parallel.js   html5勉強会lt大会
Web workers&parallel.js html5勉強会lt大会Yuta Shimakawa
 
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみる
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみるFluxのDispatcherとAction周りのことでもやもやしていることを晒してみる
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみるYuta Shimakawa
 
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料Yuta Shimakawa
 
タスクボード始めました(仮)++ アジャイルサムライ他流試合
タスクボード始めました(仮)++ アジャイルサムライ他流試合タスクボード始めました(仮)++ アジャイルサムライ他流試合
タスクボード始めました(仮)++ アジャイルサムライ他流試合Yuta Shimakawa
 
Review of work in progress November 2012
Review of work in progress   November 2012Review of work in progress   November 2012
Review of work in progress November 2012Peter Missen
 
2011.02.05 run’oプレゼン
2011.02.05 run’oプレゼン2011.02.05 run’oプレゼン
2011.02.05 run’oプレゼン大祐 伊東
 
「合併反対」所収 球団合併の要因に関する一考察
「合併反対」所収 球団合併の要因に関する一考察「合併反対」所収 球団合併の要因に関する一考察
「合併反対」所収 球団合併の要因に関する一考察Kohsuke Shinkuma
 
Review of work in progress October 2012 Part 1
Review of work in progress   October 2012 Part 1Review of work in progress   October 2012 Part 1
Review of work in progress October 2012 Part 1Peter Missen
 
Wordpress Security
Wordpress SecurityWordpress Security
Wordpress SecurityPeter Bui
 
The Solar System
The Solar System The Solar System
The Solar System Hk Sarawgi
 

Andere mochten auch (17)

型についてあれこれ
型についてあれこれ型についてあれこれ
型についてあれこれ
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
Web workers&parallel.js html5勉強会lt大会
Web workers&parallel.js   html5勉強会lt大会Web workers&parallel.js   html5勉強会lt大会
Web workers&parallel.js html5勉強会lt大会
 
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみる
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみるFluxのDispatcherとAction周りのことでもやもやしていることを晒してみる
FluxのDispatcherとAction周りのことでもやもやしていることを晒してみる
 
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料
PHPでもモダンでスケーラブルな開発を DevLOVE現場甲子園2013発表資料
 
タスクボード始めました(仮)++ アジャイルサムライ他流試合
タスクボード始めました(仮)++ アジャイルサムライ他流試合タスクボード始めました(仮)++ アジャイルサムライ他流試合
タスクボード始めました(仮)++ アジャイルサムライ他流試合
 
Technology update
Technology updateTechnology update
Technology update
 
Review of work in progress November 2012
Review of work in progress   November 2012Review of work in progress   November 2012
Review of work in progress November 2012
 
2011.02.05 run’oプレゼン
2011.02.05 run’oプレゼン2011.02.05 run’oプレゼン
2011.02.05 run’oプレゼン
 
Akaka
AkakaAkaka
Akaka
 
20110808azumaism
20110808azumaism20110808azumaism
20110808azumaism
 
「合併反対」所収 球団合併の要因に関する一考察
「合併反対」所収 球団合併の要因に関する一考察「合併反対」所収 球団合併の要因に関する一考察
「合併反対」所収 球団合併の要因に関する一考察
 
Review of work in progress October 2012 Part 1
Review of work in progress   October 2012 Part 1Review of work in progress   October 2012 Part 1
Review of work in progress October 2012 Part 1
 
Wordpress Security
Wordpress SecurityWordpress Security
Wordpress Security
 
The Solar System
The Solar System The Solar System
The Solar System
 
Technology update
Technology updateTechnology update
Technology update
 
Heal from within
Heal from withinHeal from within
Heal from within
 

Ähnlich wie Livesense tech night immutable-js at a glance

知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数Wataru Terada
 
Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?Yusuke Komatsu
 
HashTable と HashDos
HashTable と HashDosHashTable と HashDos
HashTable と HashDosYuya Takeyama
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)Ryuichi ITO
 
JavaScript/CSS 2015 Autumn
JavaScript/CSS 2015 AutumnJavaScript/CSS 2015 Autumn
JavaScript/CSS 2015 AutumnKoji Ishimoto
 
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングScalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングTanUkkii
 
今さら始めるCoffeeScript
今さら始めるCoffeeScript今さら始めるCoffeeScript
今さら始めるCoffeeScriptAshitaba YOSHIOKA
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルなおき きしだ
 
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Toshio Ehara
 
2013-12-08 西区プログラム勉強会
2013-12-08 西区プログラム勉強会2013-12-08 西区プログラム勉強会
2013-12-08 西区プログラム勉強会Takatoshi Murakami
 
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bashJun Nogata
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和schoowebcampus
 
Ruby 同好会宣言
Ruby 同好会宣言Ruby 同好会宣言
Ruby 同好会宣言Yuya Takeyama
 

Ähnlich wie Livesense tech night immutable-js at a glance (20)

知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数
 
Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?
 
What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
HashTable と HashDos
HashTable と HashDosHashTable と HashDos
HashTable と HashDos
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)
 
Testman
TestmanTestman
Testman
 
JavaScript/CSS 2015 Autumn
JavaScript/CSS 2015 AutumnJavaScript/CSS 2015 Autumn
JavaScript/CSS 2015 Autumn
 
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングScalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリング
 
今さら始めるCoffeeScript
今さら始めるCoffeeScript今さら始めるCoffeeScript
今さら始めるCoffeeScript
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイル
 
Swiftおさらい
SwiftおさらいSwiftおさらい
Swiftおさらい
 
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料
 
test
testtest
test
 
2013-12-08 西区プログラム勉強会
2013-12-08 西区プログラム勉強会2013-12-08 西区プログラム勉強会
2013-12-08 西区プログラム勉強会
 
Map
MapMap
Map
 
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
 
Ruby 同好会宣言
Ruby 同好会宣言Ruby 同好会宣言
Ruby 同好会宣言
 
Project lambda
Project lambdaProject lambda
Project lambda
 

Livesense tech night immutable-js at a glance