Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
(video at https://fsharpforfunandprofit.com/ddd/)
Statically typed functional programming languages encourage a very different way of thinking about types. The type system is your friend, not an annoyance, and can be used in many ways that might not be familiar to OO programmers. Types can be used to represent the domain in a fine-grained, self documenting way. And in many cases, types can even be used to encode business rules so that you literally cannot create incorrect code. You can then use the static type checking almost as an instant unit test — making sure that your code is correct at compile time. In this talk, we'll look at some of the ways you can use types as part of a domain driven design process, with some simple real world examples in F#. No jargon, no maths, and no prior F# experience necessary.
Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
(video at https://fsharpforfunandprofit.com/ddd/)
Statically typed functional programming languages encourage a very different way of thinking about types. The type system is your friend, not an annoyance, and can be used in many ways that might not be familiar to OO programmers. Types can be used to represent the domain in a fine-grained, self documenting way. And in many cases, types can even be used to encode business rules so that you literally cannot create incorrect code. You can then use the static type checking almost as an instant unit test — making sure that your code is correct at compile time. In this talk, we'll look at some of the ways you can use types as part of a domain driven design process, with some simple real world examples in F#. No jargon, no maths, and no prior F# experience necessary.
まるでドッグ・イヤーのごとく変化するフロントエンド開発に疲れていませんか?本セッションでは、BabelやPostCSSの導入の仕方や使い方を解説することによって、次世代の標準仕様であるEcmaScript 6やCSS 3を先取りし、長く使える技術を身につけます。流れの速さに惑わされないようにしましょう。
Koji Ishimoto @IWATE HTML5 COMMUNITY #3 on October 14
https://www.facebook.com/events/674956182641567/
The document discusses various JavaScript tools and techniques. It covers topics like transpilers like CoffeeScript and Babel, module bundlers like Browserify, task runners like Grunt and Gulp, linting with ESLint, unit testing with Mocha and Assertions, MV patterns like Flux, and components with React. It provides links to documentation and resources for learning more about each topic.
This document discusses how to collaborate with web designers. It lists an agenda with topics including conventional problems when collaborating, examples of using Smarty, PHP, and PHPTAL templating languages to separate design from coding. The document provides copyright information for kuwata-lab.com and examples of code for each templating language to iterate through a list and display items.
Jan 29, 2011, I gave a public speech to PersonaTech. This is the document originally hosted on iwork.com, but since Apple shutdown iwork.com, I hope slideshare.net can help this presentation find a place to stay.
40. 3つのオブジェクトが登場し
ています。
ここで、3つ目の、objC は
__proto__ 属性以外何も持っ
ていませんが、I Love Nicole
と表示されます。
I Love Nicole
var objA = {
name : 'Yome',
say : function () {
alert('I Love ' + this.name);
}
};
var objB = { name : 'Nikole' };
objB.__proto__ = objA;
var objC = { };
objC.__proto__ = objB;
objC.say();
41. ここでポイントになるのは、
__proto__という属性。
この__proto__を介して、
objC が objB を経て objA ま
での参照を保持できているこ
とを確認してください。
所有
所有
var objA = {
name : 'Yome',
say : function () {
alert('I Love ' + this.name);
}
};
var objB = { name : 'Nikole' };
objB.__proto__ = objA;
var objC = { };
objC.__proto__ = objB;
objC.say();
48. 同じプロト
タイプを所有
すればOK
var objA = {
name : 'Yome',
say : function () {
alert('I Love ' + this.name);
}
};
var objB = { name : 'Nikole' };
objB.__proto__ = objA;
var objC = { name : 'Gyu-Ri' };
objC.__proto__ = objA;
objB.say(); // I Love Nikole
objC.say(); // I Love Gyu-Ri
50. ‣ クラスベース ‣ プロトタイプベース
class A
class B
class C
obj A
obj B
obj C
obj A of B
obj B of C
obj C of C
obj E
obj F
extends
extends
(delegete)
new
new
(delegete)
オブジェクト
だけの世界
クラスから
オブジェクト
を作成
obj D
(delegete)
new
(delegete)
(delegete)
クラスベースではクラスという型を拡張し、そこからインスタンスを作成するイメージです。
一方プロトタイプベースでは、必要な特性を持った他のオブジェクトを利用するイメージです。
63. 利用
クラス
定義?
よく見るコードの意味
var Person = function (name) {
this.name = name;
}
Person.prototype.sayHello = function() {
alert('Hello ' + this.name);
}
var person = new Person('Nicole');
クラスは存在しないので、もちろん「クラス定義」ではありません。
78. (function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype ); // true
p.say(); // I Love Nicole
p.name = 'Gyu-Ri';
p.say(); // I Love Gyu-Ri
Person.prototype.name = 'Ha-Ra';
p.say(); // I Love Gyu-Ri
delete p.name;
p.say(); // I Love Ha-Ra
})();
SAMPLE
CODE
79. (function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
この準備で、右側のようなオブジェ
クトが出来ます(コンストラクタ
関数の実行部は省略)。
ここで、Person.prototype に
入っているオブジェクトは、name
と say の2つの属性を持ちます。
80. (function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
new した時の擬似コード
var newObj = {};
newObj.__proto__ =
Person.apply(newObj, ['Nicole'])
return newObj;
Person を newすると、擬似コードにあるような初期化が行われ、新しい
オブジェクトの __proto__ に Person.prototype のオブジェクトが代入されます。
代入
81. p: {
name:'Nicole'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
参照
結果、新しいオブジェクト p の __proto__ は、
Person.prototype に入っているオブジェクトへの参照を持ちます。
82. p: {
name:'Nicole'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
True
同じ
Person.prototype が p.__proto__ に代入された直後なので、
当然ですが、同一性比較は true になります。
83. p: {
name:'Nicole'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
I Love Nicole
参照
p.say() がコールされると、p 上に say を探すが見つかりません。
__proto__を って、say を見つけます。name は p 上で見つかります。
84. p: {
name:'Gyu-Ri'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'nanashi'
say: functon () {…}
}
}
I Love Gyu-Ri
参照
先ほどと同じですが、p 自身が持つ name が変更されたため、
当然、表示される内容は変化します。
85. p: {
name:'Gyu-Ri'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'Ha-Ra'
say: functon () {…}
}
}
I Love Gyu-Ri
参照
Person.prototype.name を変更しましたが、
name は p 自身で見つかるので、結果に変化はありません。
86. p: {
name:'Gyu-Ri'
__proto__:
}
(function() {
var Person = function (name){
this.name = name;
};
Person.prototype.name = 'nanashi';
Person.prototype.say = function () {
alert('I Love ' + this.name);
};
var p = new Person('Nicole');
alert( p.__proto__ === Person.prototype );
p.say();
p.name = 'Gyu-Ri';
p.say();
Person.prototype.name = 'Ha-Ra';
p.say();
delete p.name;
p.say();
})();
Person: {
prototype: {
name:'Ha-Ra'
say: functon () {…}
}
}
I Love Ha-Ra
参照
p 自身の name を削除すると、p 自身は name を持たなくなるので、
say も name も __proto__ から検索されて、結果、表示内容が変わります。
削除されて無くなった
100. 名前が同じでも
スコープが違えば
別の変数
var name = 'Nicole';
function myfunc() {
var name = 'Gyu-Ri';
}
myfunc();
alert(name); //Nicole
別の変数なので、関数内
での代入は外側の name
に影響しない。
101. じゃ、これは?
var name = 'Nicole';
function myfunc() {
name = 'Gyu-Ri';
}
myfunc();
alert(name); //???
102. var name = 'Nicole';
function myfunc() {
name = 'Gyu-Ri';
}
myfunc();
alert(name); //Gyu-Ri
同じ変数!!
同じ変数なので、関数内
で 代 入 し た ら 外 側 の
name も変わる。
110. 外側の変数
は見える
var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
さっきの例の
変数 a の場合
111. このローカルスコープで、宣言さ
れているのは c だけなので、
a と b は 既にあると解釈される
…でも、func2 のローカルスコー
プには、a と b は見つからない。
var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
112. var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
そこで JavaScript は、一つ外側
の func1 のスコープで a と b を
検索する。
そして、b を見つけるが、
まだ a は見つからない。
113. var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
そこで JavaScript は、さらに
外側のスコープで a を検索し、
そして a を発見する。
129. var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
この関数が
定義された
環境とは…
130. var a = 123;
function func1() {
var b = 3;
function func2() {
var c = 2;
alert(a * b * c);
}
func2();
}
func1(); //738と表示
この関数を含
む全てのスコー
プのこと
スコープチェインによって、
関数定義の外側の変数まで
参照できましたよね!
145. これは
OK
var Person = function (name) {
this.name = name;
}
Person.prototype.sayHello = function() {
alert('Hello ' + this.name);
}
var person = new Person('Nicole');
var btn = $('button#say-hello');
btn.on('click', function() {
person.sayHello();
});
よくあるパターンです。イベントにコールバック関数をバインドしています。
ここで、btn.on に渡している関数はクロージャで、クロージャ変数として
person を参照しています。
146. これは
NG
var Person = function (name) {
this.name = name;
}
Person.prototype.sayHello = function() {
alert('Hello ' + this.name);
}
var person = new Person('Nicole');
var btn = $('button');
btn.on('click', person.sayHello);
前の例では、呼び出したい関数をコールバックとして登録しているだけだったので、
sayHello 関数を直接バインドしたらどうだろう?とやってみると NG です…。
結果として、(多くの場合)「Hello undefined」と表示されます。
169. person を this
として実行
call の第1引数が this に、
第2引数以降の引数が、
say関数の引数に。
function say(arg1, arg2) {
alert(arg1 + this.name + arg2);
}
var person = new Person('Nicole');
say.call(person, 'Hello ', ' chan');
call の例
170. person を this
として実行
apply の例
call の第1引数が this に、第2引数の
配列の内容が、say関数の引数になる。
引数の渡し方以外は
call と同じ
function say(arg1, arg2) {
alert(arg1 + this.name + arg2);
}
var person = new Person('Nicole');
say.apply(person, ['Hello ', ' chan']);
171. 他のオブジェクト
のメンバだったら?
var p1 = {
name: 'Gyu-Ri',
say: function (arg1, arg2) {
alert(arg1 + this.name + arg2);
}
};
var person = new Person('Nicole');
p1.say.call(person, 'Hello ', ' chan');
172. 他のオブジェクト
のメンバでも関係ない
関数はオブジェクトに「束縛されていない」
ことを思い出してください。
ここで、関数 say が p1 に属していても、
指定した person が this になります。
var p1 = {
name: 'Gyu-Ri',
say: function (arg1, arg2) {
alert(arg1 + this.name + arg2);
}
};
var person = new Person('Nicole');
p1.say.call(person, 'Hello ', ' chan');
176. これは
NGでした
さきほど NG だった例ですが...
var Person = function (name) {
this.name = name;
}
Person.prototype.sayHello = function() {
alert('Hello ' + this.name);
}
var person = new Person('Nicole');
var btn = $('button');
btn.on('click', person.sayHello);
177. こうすれば
OK
bind で関数に this を束縛できるので、そのまま渡せるようになる。
person を2回使ってるように見えるけど、そういう意味でないことに注意。
var Person = function (name) {
this.name = name;
}
Person.prototype.sayHello = function() {
alert('Hello ' + this.name);
}
var person = new Person('Nicole');
var btn = $('button');
btn.on('click', person.sayHello.bind(person));