SlideShare a Scribd company logo
1 of 48
Download to read offline
第一級関数と作用的プログラミング
JavaScript*で学ぶ関数型プログラミング*2*章
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 1
内容
• 第一級要素としての関数
• JavaScript+のプログラミングパラダイムについて
• 作用的プログラミング・コレクション中心プログラミング
• データ思考プログラミング
• テーブルのようなデータの取り扱い
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 2
第一級要素としての関数
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 3
第一級関数
• JavaScript+の第一級要素+:+数値・文字列+...+関数
• つまり関数と数値や文字列は同じ性質を持つ
• 変数に代入可能
• 任意のタイミングで生成可能
• 関数の引数・戻り値になる+3
3
"ここでは""関数型""を言語に対する形容詞として使っていない
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 4
// 変数・配列・オブジェクトのフィールドに代入可能
var f = function() { return 42 },
a = [42, function() { return 42 }],
o = {n: 42, f: function() { return 42 }};
// 任意のタイミングで生成可能
42 + (function(){ return 42 })(); //=> 84
// 引数・返り値に取ることが可能 (恒等関数での例)
function identity(x) { return x };
identity(function() { return 42 }); //=> function()
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 5
閑話休題:"JavaScript"は関数型言語か?"1
• そもそも""関数型言語""の基準は?
• 関数が第一級要素?
• 参照透過性?
• 副作用の隠 ?
• 型推論?
1
"h$p://www.slideshare.net/ksknac/120901fp9key"(24"ページ)
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 6
そもそも関数型とは?!2
• 以下のようなプログラミング"パラダイム"に対する形容"3
• プログラムのほとんどが関数であるような書き方
• 非関数や副作用の影響を可能な限り小さくする
• 使用する言語に関係なく実現が可能
3
"ここでは""関数型""を言語に対する形容詞として使っていない
2
"h$p://www.slideshare.net/ksknac/120901fp9key"(25"ページ)
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 7
改めて:"JavaScript"は関数型言語か?
• 関数型(パラダイムのプログラミングをしやすい)言語か?
• JavaScript-では関数が第一級要素となっている
• 関数型スタイルでのプログラミングはしやすい
• その他の関数型の機能は言語としてサポートはされていない
→書き手の配慮により関数型スタイルで書くことが可能な言語-
4
""変数再代入をしない""とか""関数は必ず値を返し、副作用がないようにする""とか。
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 8
JavaScript*の*
*プログラミングパラダイム
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 9
・!命令型プログラミング
・!関数型プログラミング
・!プロトタイプベースオブジェクト指向
・!メタプログラミング
5
"よく見られるものを示した。ES6"からクラスベースオブジェクト指向も見られるようになるかも。
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 10
命令型プログラミング
• 実行フローをほぼそのまま書き下す
• プログラムの実行状態を直接操作・参照する
• 対となるパラダイムは"宣言型プログラミング
• 関数型や論理型は宣言型プログラミングに属する
• C"言語・BASIC・PASCAL"等はこのパラダイムを取る事が多い
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 11
例)"99"本のビール
• 99#から開始し、1#ずつ引いていき繰り返す
• 現在の数を#X#として、次のように歌う
• X#本のビールが残ってる#=>#X#本のビール
• ひとつ取って、隣に回せ#=>#X(1#本のビールが残ってる
• X=1#の時は最後の部分で#もうビールは残ってない#と歌う。
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 12
// 命令型プログラミング
var lyrics = [];
for (var bottles = 99; bottles > 0; bottles--) {
lyrics.push(bottles + " 本のビールが残ってる");
lyrics.push(bottles + " 本のビール");
lyrics.push("ひとつ取って、隣に回せ");
if (bottles > 1) {
lyrics.push((bottles - 1) + "本のビールが残ってる");
}
else {
lyrics.push("もうビールは残ってない");
}
}
// この後に 80∼50 本のビールの歌を歌わせたかったら...?
// この部分のテストが書きたくなったら...?
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 13
// 関数型スタイルへのパラダイムシフト
// "n 本目のビールの歌詞を生成する" 機能を関数へと分割
function lyricSegment(n) {
return _.chain([]) // メソッドチェイン記法
.push(n + " 本のビールが残ってる")
.push(n + " 本のビール")
.push("ひとつ取って、隣に回せ")
.tap(function(lyrics) { // 渡ってきたオブジェクトに関数を適用しオブジェクトを返す
if (n > 1)
lyrics.push((n - 1) + " 本のビールが残ってる");
else
lyrics.push("もうビールは残ってない");
})
.value(); // 値を返す
}
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 14
// 関数の繋ぎあわせ
function song(start, end, lyricGen) {
return _.reduce(_.range(start,end,-1), // 値を返す
function(acc,n) {
return acc.concat(lyricGen(n)); // 値を返す
}, []);
}
song(99, 0, lyricSegment)
// => ["99 本のビールが残ってる", "99 本のビール", "ひとつ取って、隣に回せ", ... ]
// song(80, 50, lyricSegment) で 80∼50 本のビールの歌が歌える
// 正しく値が返って来ているかのテストも書きやすそう
// 歌詞生成部だけのテストも書けそう
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 15
命令型と関数型
• 前述の例のように、ルールを守って処理を細かく関数に分ける
• 命令型では"99"本・同じ歌詞でしか動かせなかった
• 関数型では関数として定義することにより抽象的に
• 99"本のビール,"30"本のビール..."は"song"関数ですぐ作れる
6
"英語で歌わせたければ"enLyricSegment"のような関数を用意し"song(99,"0,"enlyricsegment)"のようにすればよい
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 16
何が良いと感じたか
• 機能別に分けることにより
• 変更に強いプログラムが作れる
• 再利用性が高く同じようなコードを何度も書かなくて良い
• 機能毎のテストが書きやすくなる
• 参照等価にするとここが∼みたいな話は色々あるけど...#7
7
"とりあえずここまでの例で読み取れることのみの感想です
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 17
プロトタイプベースオブジェクト指向
• JavaScript+のオブジェクト指向はプロトタイプベース
• 既存のオブジェクトをプロトタイプとして使用する+8
• クラス指向のオブジェクト指向に対してローレベルで動作する
• 柔軟性はあるが罠も多い
8
"以降「関数」は単独で存在する関数、「メソッド」はオブジェクトのコンテキストに生成された関数を指す
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 18
罠
// オブジェクトのフィールド値に関数が存在できる
var a = {name: "a", f: function(){return this}};
// this は a 自身を指す。計画通り。
a.f() // => {name: "a", f: ...}
var bObj = {name: "b", f: function(){return this}},
var bFun = bObj.f;
// !! this は bObj を指さない !! bFun から見た this を指す !!
bFun() // => グローバルオブジェクト (window など)
8
"以降「関数」は単独で存在する関数、「メソッド」はオブジェクトのコンテキストに生成された関数を指す
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 19
メタプログラミング
• ソースコードを生成するようなプログラムを書くスタイル
• 本書では、以下のような例が紹介されている"9
function Point2D(x, y) { this._x = x; this._y = y; }
function Point3D(x, y, z) { Point2D.call(this, x, y); this._z = z; }
new Point3D(10, -1, 100);
//=> {_x: 10, _y: -1, _z: 100}
• 本書ではほぼ取り扱わないので詳細は省略する
9
"この例があまりメタプログラミングっぽく見えないのは"JavaScript"のデータ構造とプログラム構造が近いから?
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 20
作用的プログラミング!
!コレクション中心プログラミング
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 21
作用的プログラミング
• 関数"f: A()"と"f: B()"を次のように使用するプログラミング
• B"を呼び出すことで"A"を実行させる"10
• B(element, A())
• "作用的"という言葉はコンテキストによって異なる意味を持つ
• もう使わないけど意味だけは知っておいてね
10
#と、本書では定義してあるのでこのスライドでもそう定義します。
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 22
作用的プログラミングの例
var nums = [1,2,3,4,5];
function doubleAll(array) {
return _.map(array, function(n) { return n*2 });
}
doubleAll(nums); //=> [2, 4, 6, 8, 10]
// ---------------------
function average(array) {
var sum = _.reduce(array, function(a, b) { return a+b });
return sum / _.size(array);
}
average(nums); //=> 3
// ---------------------
function onlyEven(array) {
return _.filter(array, function(n) { return (n%2) === 0; });
}
onlyEven(nums);
//=> [2, 4]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 23
コレクション中心プログラミング
• 関数型プログラミング
• コレクションに入った多数の値に同じ処理をしやすい
• [1, 2, 3, 4, 5]"や"{a: 1, b: 2}"...
• 本書はこの考え方に則りデータ構造を有効活用する方法を推進
• It#is#be(er#to#have#100#func4ons#operate#on#one#data#structure#than#
10#func4ons#on#10#data#structures.#88#Alan#Perlis
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 24
コレクション中心プログラミングの例
_.map({a: 1, b: 2}, _.identity); //=> [1,2]
// ---------------------
_.map({a: 1, b: 2}, function(v,k) { return [k,v]; });
//=> [['a', 1], ['b', 2]]
// ---------------------
_.map({a: 1, b: 2}, function(v,k,coll) {
return [k, v, _.keys(coll)];
});
//=> [['a', 1, ['a', 'b']], ['b', 2, ['a', 'b']]]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 25
作用的プログラミングのその他の例
// ReduceRight
var nums = [100,2,25];
function div(x,y) { return x/y };
_.reduce(nums, div); //=> 2
_.reduceRight(nums, div); //=> 0.125
// allOf, anyOf; reduce でも同じように記述できる
function allOf(/* funs */) {
return _.reduceRight(arguments, function(truth, f) {
return truth && f();
}, true);
}
function anyOf(/* funs */) {
return _.reduceRight(arguments, function(truth, f) {
return truth || f();
}, false);
}
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 26
// ReduceRight
// allOf, anyOf の使用例
function T() { return true }
function F() { return false }
allOf(); //=> true
allOf(T, T); //=> true
allOf(T, T, T , T , F); //=> false
anyOf(T, T, F); //=> true
anyOf(F, F, F, F); //=> false
anyOf(); //=> false
• reduce/reduceRight-は演算が結合的でない時に差が発生
• 遅延評価の言語ではもっと大きな違いがある
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 27
// find, reject, filter, all, any
// find: コレクションとプレディケートを取り真となる要素を返す
_.find(['a', 'b', 3, 'd'], _.isNumber); //=> 3
// find の逆の動作; underscore.js は _.isNumber のようなプレディケート関数を多数用意している
_.reject(['a', 'b', 3, 'd'], _.isNumber); //=> ['a', 'b', 'd']
// 真偽を判定させる関数 complement
function complement(pred) {
return function() { return !pred.apply(null, _.toArray(arguments)); };
}
// _.reject と同じ動作
_.filter(['a', 'b', 3, 'd'], complement(_.isNumber)); //=> ['a', 'b', 'd']
// all: 要素のすべてが true の時 true; any: 要素の1つでも true なら true
_.all([1, 2, 3, 4], _.isNumber); //=> true
_.any([1, 2, 'c', 4], _.isString); //=> true
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 28
// sortBy, countBy, groupBy
var people = [{name: "Rick", age: 30}, {name: "Jaka", age: 24}];
// コレクションと関数を受け取り関数の基準に応じて並べ替えたコレクションを返す
_.sortBy(people, function(p) { return p.age });
//=> [{name: "Jaka", age: 24}, {name: "Rick", age: 30}]
var albums = [{title: "Sabbath Bloody Sabbath", genre: "Metal"},
{title: "Scientist", genre: "Dub"},
{title: "Undertow", genre: "Metal"}];
// 受け取った関数が返す値をキーとして、その値が等しいオブジェクトを配列に入れて返す
_.groupBy(albums, function(a) { return a.genre });
//=> {Metal:[{title:"Sabbath Bloody Sabbath", genre:"Metal"},
// {title:"Undertow", genre:"Metal"}],
// Dub: [{title:"Scientist", genre:"Dub"}]}
// _.groupBy と同じ動作をするが、キーに対応する値が配列の長さになっている
_.countBy(albums, function(a) { return a.genre }); //=> {Metal: 2, Dub: 1}
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 29
作用的関数の定義
// 作用的ではない関数達
// 幾つかの配列を結合する関数
function cat() {
var head = _.first(arguments);
if (existy(head))
return head.concat.apply(head, _.rest(arguments));
else
return [];
}
cat([1,2,3], [4,5], [6,7,8]); //=> [1, 2, 3, 4, 5, 6, 7, 8]
// 要素と配列を引数に取り配列の前に要素を挿入する関数
// これも作用的な関数ではない
function construct(head, tail) {
return cat([head], _.toArray(tail));
}
construct(42, [1,2,3]); //=> [42, 1, 2, 3]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 30
// 作用的な関数 mapcat
// _.map を使用し fun を受け取り渡されたコレクションの要素全てに対して fun を実行する
// その後 _.map から返された全ての要素を結合する
function mapcat(fun, coll) {
return cat.apply(null, _.map(coll, fun));
}
mapcat(function(e) {
return construct(e, [","]);
}, [1,2,3]);
// => [1, ",", 2, ",", 3, ","]
// construct は要素を配列の先頭に挿入する関数
// 内部的には: cat.apply(null, [[1, ","], [2, ","], [3, ","]])
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 31
function butLast(coll) {
return _.toArray(coll).slice(0, -1);
}
function interpose (inter, coll) {
return butLast(mapcat(function(e) {
return construct(e, [inter]);
}, coll));
}
interpose(",", [1,2,3]);
//=> [1, ",", 2, ",", 3]
// ([1, 2, 3] => [1, ",", 2, ",", 3, ","] => [1, "," 2, ",", 3])
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 32
作用的関数
• 低レベルの関数によって組み立てられた個別の機能を組合わせ
• 複数の関数が作用的に呼び出される
• それぞれの関数がデータを処理し最後の解に至る
• 関数型プログラミングの重要な切り口
• 今後本書ではこのようなパターンが多数登場
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 33
データ思考
• JavaScript+におけるオブジェクト型は非常に強力
• ポリモーフィックディスパッチ/単純な連想データストア
• データストアとして扱う関数は+JavaScript+自体にはほぼ無い
• Underscore+が有用なツールを提供し、オブジェクト等に特化
しない一意な定義が可能+11
11
"「情報の断片ごとに定義された、マイクロ言語のようなもの」(Hickey"2011)"から逃れられる
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 34
// keys/values は key/value を返す(当然)
var zombie = {name: "Bub", film: "Day of the Dead"};
_.keys(zombie); //=> ["name", "film"]
_.values(zombie); //=> ["Bub", "Day of the Dead"]
// pluck は 指定したキーの要素を全て返す(無い時は undefined)
_.pluck([{title: "Chthon", author: "Anthony"},
{title: "Grendel", author: "Gardner"},
{title: "After Dark"}], 'author');
//=> ["Anthony", "Gardner", undefined]
// pairs は {a: b, c: d} を [[a, b], [c, d]] とする
_.pairs(zombie);
//=> [["name", "Bub"], ["film", "Day of the Dead"]]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 35
// シーケンシャルな処理を行い、_.object でオブジェクトを再構成する例
_.object(_.map(_.pairs(zombie), function(pair) {
return [pair[0].toUpperCase(), pair[1]];
}));
//=> {FILM: "Day of the Dead", NAME: "Bub"};
// _.invert はキーと値を入れ替える
_.invert(zombie);
//=> {"Bub": "name", "Day of the Dead": "film"}
// JavaScript のキーは必ず文字列になる
_.keys(_.invert({a: 138, b: 9})); //=> ['9', '138']
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 36
// _.defaults は指定したキーが存在しない場合デフォルト値として追加する
_.pluck(_.map([{title: "Chthon", author: "Anthony"},
{title: "Grendel", author: "Gardner"},
{title: "After Dark"}],
function(obj) {
return _.defaults(obj, {author: "Unknown"})
}), 'author');
//=> ["Anthony", "Gardner", "Unknown"]
// _.pick, _.omit は引数によりオブジェクトの内容をフィルタする (非破壊的操作)
var person = {name: "Romy", token: "j3983ij", password: "tigress"};
var info = _.omit(person, 'token', 'password');
info; //=> {name: "Romy"}
var creds = _.pick(person, 'token', 'password');
//=> {password: "tigress", token: "j3983ij"};
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 37
// findWhere, where は 2 番目の引数の条件にマッチするオブジェクトを
// 1 番目の引数から探してくる
var library = [{title: "SICP", isbn: "0262010771", ed: 1},
{title: "SICP", isbn: "0262510871", ed: 2},
{title: "Joy of Clojure", isbn: "1935182641", ed: 1}];
// findWhere は最初にマッチしたものだけが返る
_.findWhere(library, {title: "SICP", ed: 2});
//=> {title: "SICP", isbn: "0262510871", ed: 2}
// where はマッチした全ての要素が配列で返る
_.where(library, {title: "SICP"});
//=> [{title: "SICP", isbn: "0262010771", ed: 1},
// {title: "SICP", isbn: "0262510871", ed: 2}]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 38
テーブルのようなデータ
• 前項で示した"library"のようなデータの取り扱い
• JavaScript"のオブジェクトの配列をデータテーブルとして見る
• 行が"JavaScript"オブジェクト/セルがオブジェクトのキー値ペア
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 39
テーブルのようなデータ!2
• タイトルを抜き出したテーブル
SELECT title FROM library;
_.pluck(library, 'title'); // ここまでで習った JavaScript での同等の表現
// 但し、オブジェクトから配列に変換されており、型が壊れている ...
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 40
// _.pick を使用しテーブルデータの抽象型を維持する
function project(table, keys) {
return _.map(table, function(obj) {
return _.pick.apply(null, construct(obj, keys));
});
};
var editionResults = project(library, ['title', 'isbn']);
// => [{isbn: "0262010771", title: "SICP"},
// {isbn: "0262510871", title: "SICP"},
// {isbn: "1935182641", title: "Joy of Clojure"}];
// (_.pick.apply(null, [{...}, 'title', 'isbn']) が要素ごとに実行される)
// データ構造を維持したまま値を返すため、更に project を適用可能
var isbnResults = project(editionResults, ['isbn']);
//=> [{isbn: "0262010771"}, {isbn: "0262510871"}, {isbn: "1935182641"}]
_.pluck(isbnResults, 'isbn'); // 欲しいデータだけを取得する
//=> ["0262010771", "0262510871", "1935182641"]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 41
データの抽出
• 上記で見たようなデータ構造を破壊して必要な値を得る操作
• あるモジュールから別のモジュールへデータを「引渡す」操作
• 関数型スタイルではデータの内容/変換/フォーマットを考える
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 42
抽象テーブル型
• SQL%では%AS%句を使ってカラムに別名を与えることが可能
SELECT ed AS edition FROM library; /* 下のテーブルのような出力 */
• 次に、JavaScript+で+as+や+where+を実装してみる
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 43
// マップデータを指定した通りにリネームする関数
function rename(obj, newNames) {
return _.reduce(newNames, function(o, nu, old) {
if (_.has(obj, old)) {
o[nu] = obj[old]; return o;
}
else
return o;
},
_.omit.apply(null, construct(obj, _.keys(newNames))));
};
rename({a: 1, b: 2}, {'a': 'AAA'}); //=> {AAA: 1, b: 2}
// オブジェクトの再構成に _.reduce を使用している
// これによってマップデータらしさを維持しつつキーの名前を変換している
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 44
// rename 関数を使用し実装した as 関数
function as(table, newNames) {
return _.map(table, function(obj) {
return rename(obj, newNames); });
};
as(library, {ed: 'edition'});
//=> [{title: "SICP", isbn: "0262010771", edition: 1},
// {title: "SICP", isbn: "0262510871", edition: 2},
// {title: "Joy of Clojure", isbn: "1935182641", edition: 1}]
// as はテーブルデータ型を返すので project, as を同時に適用可能
project(as(library, {ed: 'edition'}), ['edition']);
//=> [{edition: 1}, {edition: 2}, {edition: 1}];
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 45
// プレディケートを受け取りそれぞれのオブジェクトに対して適用する関数
function restrict(table, pred) {
return _.reduce(table, function(newTable, obj) {
if (truthy(pred(obj)))
return newTable;
else
return _.without(newTable, obj);
}, table);
};
restrict(library, function(book) { return book.ed > 1; });
//=> [{title: "SICP", isbn: "0262510871", ed: 2}]
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 46
SELECT title, isbn, edition FROM (
SELECT ed AS edition FROM library
) EDS
WHERE edition > 1;
/* SQL での例 */
// 上記の SQL と同等な JavaScript を使った例
restrict(
project(
as(library, {ed: 'edition'}),
['title', 'isbn', 'edition']),
function(book) {
return book.edition > 1;
});
//=> [{title: "SICP", isbn: "0262510871", edition: 2},]
// restrict, as, project は同じテーブル抽象型(オブジェクトの配列)に対して動作する
// これがデータ思考プログラミング
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 47
まとめ
• JavaScript+の関数型(スタイルで書ける)言語としての側面
• 第一級関数/手続き型から関数型スタイルへの書き換え
• JavaScript+の様々なプログラミングパラダイムについて
• 作用的プログラミングについて
• コレクション中心プログラミング/テーブル様データの取扱い
YOSHIKAWA)Ryota)(2015/1/22|2015/2/11))第一回/第二回)Topotal)輪読会 48

More Related Content

What's hot

RubyとJavaScriptに見る第一級関数
RubyとJavaScriptに見る第一級関数RubyとJavaScriptに見る第一級関数
RubyとJavaScriptに見る第一級関数Altech Takeno
 
現実(えくせる)と戦う話
現実(えくせる)と戦う話現実(えくせる)と戦う話
現実(えくせる)と戦う話bleis tift
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語RShuyo Nakatani
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~Fujio Kojima
 
Python基礎その1
Python基礎その1Python基礎その1
Python基礎その1大貴 末廣
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development lifeUehara Junji
 
Python基礎その2
Python基礎その2Python基礎その2
Python基礎その2大貴 末廣
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7Kenta Hattori
 
分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用y-uti
 
TaPL読書会 #9 ~ §14 Exception
TaPL読書会 #9 ~ §14 ExceptionTaPL読書会 #9 ~ §14 Exception
TaPL読書会 #9 ~ §14 ExceptionAkihiro Miyashita
 
科学技術計算関連Pythonパッケージの概要
科学技術計算関連Pythonパッケージの概要科学技術計算関連Pythonパッケージの概要
科学技術計算関連Pythonパッケージの概要Toshihiro Kamishima
 
DS Exercise Course 2
DS Exercise Course 2DS Exercise Course 2
DS Exercise Course 2大貴 末廣
 
Introduction to lambda calculation
Introduction to lambda calculationIntroduction to lambda calculation
Introduction to lambda calculationrelipmoc101
 
Python 機械学習プログラミング データ分析演習編
Python 機械学習プログラミング データ分析演習編Python 機械学習プログラミング データ分析演習編
Python 機械学習プログラミング データ分析演習編Etsuji Nakai
 
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-Takuya Akiba
 
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapSwift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapTomohiro Kumagai
 
[第2版]Python機械学習プログラミング 第8章
[第2版]Python機械学習プログラミング 第8章[第2版]Python機械学習プログラミング 第8章
[第2版]Python機械学習プログラミング 第8章Haruki Eguchi
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Yasutomo Kawanishi
 

What's hot (20)

RubyとJavaScriptに見る第一級関数
RubyとJavaScriptに見る第一級関数RubyとJavaScriptに見る第一級関数
RubyとJavaScriptに見る第一級関数
 
現実(えくせる)と戦う話
現実(えくせる)と戦う話現実(えくせる)と戦う話
現実(えくせる)と戦う話
 
普通のプログラミング言語R
普通のプログラミング言語R普通のプログラミング言語R
普通のプログラミング言語R
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
 
Python基礎その1
Python基礎その1Python基礎その1
Python基礎その1
 
Linqことはじめ
LinqことはじめLinqことはじめ
Linqことはじめ
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development life
 
Python基礎その2
Python基礎その2Python基礎その2
Python基礎その2
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7
 
分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用
 
TaPL読書会 #9 ~ §14 Exception
TaPL読書会 #9 ~ §14 ExceptionTaPL読書会 #9 ~ §14 Exception
TaPL読書会 #9 ~ §14 Exception
 
科学技術計算関連Pythonパッケージの概要
科学技術計算関連Pythonパッケージの概要科学技術計算関連Pythonパッケージの概要
科学技術計算関連Pythonパッケージの概要
 
DS Exercise Course 2
DS Exercise Course 2DS Exercise Course 2
DS Exercise Course 2
 
Introduction to lambda calculation
Introduction to lambda calculationIntroduction to lambda calculation
Introduction to lambda calculation
 
Python 機械学習プログラミング データ分析演習編
Python 機械学習プログラミング データ分析演習編Python 機械学習プログラミング データ分析演習編
Python 機械学習プログラミング データ分析演習編
 
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
 
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapSwift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
 
[第2版]Python機械学習プログラミング 第8章
[第2版]Python機械学習プログラミング 第8章[第2版]Python機械学習プログラミング 第8章
[第2版]Python機械学習プログラミング 第8章
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
 

Similar to 【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章

Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Norito Agetsuma
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)Hiroaki KOBAYASHI
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Ra Zon
 
Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Hisakuni Fujimoto
 
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Shintaro Fukushima
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようShinsuke Sugaya
 
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章Last Arrow
 
20160215 04 java ee7徹底入門 jbatch
20160215 04 java ee7徹底入門 jbatch20160215 04 java ee7徹底入門 jbatch
20160215 04 java ee7徹底入門 jbatchJun Inose
 
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたjvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたKazuyoshi Kamitsukasa
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能Soudai Sone
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】株式会社ランチェスター
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングTanUkkii
 
第一回Data mining勉強会 -第二章
第一回Data mining勉強会 -第二章第一回Data mining勉強会 -第二章
第一回Data mining勉強会 -第二章Tomonobu_Hirano
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)信之 岩永
 

Similar to 【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章 (20)

Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門Swiftによる関数型プログラミング超入門
Swiftによる関数型プログラミング超入門
 
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめよう
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章
 
Dotnetconf2017
Dotnetconf2017Dotnetconf2017
Dotnetconf2017
 
20160215 04 java ee7徹底入門 jbatch
20160215 04 java ee7徹底入門 jbatch20160215 04 java ee7徹底入門 jbatch
20160215 04 java ee7徹底入門 jbatch
 
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたjvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
 
第一回Data mining勉強会 -第二章
第一回Data mining勉強会 -第二章第一回Data mining勉強会 -第二章
第一回Data mining勉強会 -第二章
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 

【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章