WEBVTT

00:00:00.520 --> 00:00:03.880 align:middle
このセッションでは
メッセージの合成を学びます。

00:00:04.040 --> 00:00:08.720 align:middle
優先順位がどのように働くか
階層を見ます。

00:00:08.880 --> 00:00:11.600 align:middle
まず問題ですが

00:00:11.760 --> 00:00:15.080 align:middle
「単項メッセージのシーケンスがある場合には
何が起こるでしょうか？」

00:00:15.240 --> 00:00:18.040 align:middle
次のような表現式があるとします。

00:00:18.200 --> 00:00:20.720 align:middle
1000 factorial class name
何が起こるでしょう？

00:00:20.880 --> 00:00:24.400 align:middle
これらの括弧があるのと同じように
実行されます。

00:00:24.560 --> 00:00:26.680 align:middle
見ての通り煩雑ですね。

00:00:26.840 --> 00:00:30.840 align:middle
同じレベルのメッセージが複数ある場合

00:00:31.000 --> 00:00:35.000 align:middle
(単項、二項またはキーワードの
いずれでも同じです）

00:00:35.160 --> 00:00:37.320 align:middle
左から右に評価されていきます。

00:00:37.480 --> 00:00:40.280 align:middle
まず 1000 に factorial メッセージ(階乗)
を送ります。

00:00:40.440 --> 00:00:43.960 align:middle
そして factorial の結果に対して
class メッセージを送ります。

00:00:44.120 --> 00:00:46.600 align:middle
そしてこの新しいオブジェクトに

00:00:47.800 --> 00:00:50.600 align:middle
name メッセージが投げられます。

00:00:50.760 --> 00:00:52.880 align:middle
LargePositiveInteger が返ってきます。

00:00:53.640 --> 00:00:56.080 align:middle
1000の階乗(factorial)は大きな数です。

00:00:56.240 --> 00:00:59.320 align:middle
10000の階乗を試すこともできます。

00:00:59.920 --> 00:01:01.160 align:middle
するとさらにもう少し「長い」数になります。

00:01:02.160 --> 00:01:06.160 align:middle
括弧つきのメッセージもあります。

00:01:06.320 --> 00:01:08.520 align:middle
先に実行される必要がある時です。

00:01:08.680 --> 00:01:11.960 align:middle
次に単項メッセージ、次に二項メッセージ
その次にキーワードメッセージです。

00:01:12.120 --> 00:01:15.200 align:middle
同じレベルの場合には
左から右へ行きます。

00:01:15.920 --> 00:01:17.720 align:middle
1つ例題をやってみましょう。

00:01:17.880 --> 00:01:21.800 align:middle
単項メッセージ squared と

00:01:21.960 --> 00:01:24.480 align:middle
二項メッセージ + があります。

00:01:24.640 --> 00:01:27.000 align:middle
単項メッセージが勝ちます。

00:01:27.160 --> 00:01:30.800 align:middle
まず squared を送信して

00:01:30.960 --> 00:01:33.760 align:middle
次に + メッセージを送信します。

00:01:33.920 --> 00:01:36.640 align:middle
11が返ってきます。正解です。

00:01:37.480 --> 00:01:39.560 align:middle
別の状況があります。

00:01:39.720 --> 00:01:42.360 align:middle
raisedTo: メッセージで累乗を求めます。

00:01:42.520 --> 00:01:47.040 align:middle
二項メッセージとキーワードがあります。
二項メッセージが勝ちます。

00:01:47.200 --> 00:01:49.520 align:middle
まず 5 が得られ

00:01:49.680 --> 00:01:53.080 align:middle
そして raisedTo: が実行され 32が返ってきます。
正解です。

00:01:54.000 --> 00:01:56.160 align:middle
これはもう少し複雑な例です。

00:01:56.320 --> 00:02:00.120 align:middle
Pharo では色はオブジェクトです。

00:02:00.280 --> 00:02:01.680 align:middle
Color クラスがあります。

00:02:01.840 --> 00:02:06.240 align:middle
3つの単項メッセージがあります。
gray と white と black です。

00:02:06.400 --> 00:02:11.360 align:middle
2つの二項メッセージがあります。
= と - です。

00:02:11.520 --> 00:02:16.160 align:middle
では何が起こるでしょう？
システムはまず各単項メッセージを実行します。

00:02:16.840 --> 00:02:21.320 align:middle
それぞれ灰色、白、黒の
オブジェクトを返します。

00:02:21.480 --> 00:02:25.080 align:middle
そしてメッセージを送ります。

00:02:25.240 --> 00:02:28.560 align:middle
- メッセージと = メッセージから
選ばなければなりません。

00:02:29.520 --> 00:02:34.480 align:middle
灰色オブジェクトに - メッセージを
白を引数として送ります。

00:02:34.640 --> 00:02:36.800 align:middle
黒が返ってきます。

00:02:37.520 --> 00:02:41.520 align:middle
2つの色を比較します。
黒 = 黒になります。trueです。

00:02:43.320 --> 00:02:46.160 align:middle
この例題は

00:02:47.360 --> 00:02:50.200 align:middle
Pharoで自動変換ができるというもので

00:02:50.360 --> 00:02:52.880 align:middle
ある種の冗談です。

00:02:53.960 --> 00:02:57.960 align:middle
この表現式です。
1 class maxVal + 1

00:02:58.120 --> 00:03:00.920 align:middle
2つの単項メッセージがあります。
class と maxVal です。

00:03:01.080 --> 00:03:02.400 align:middle
そして二項メッセージが1つです。

00:03:03.640 --> 00:03:05.720 align:middle
この表現式はどう実行されるでしょうか？

00:03:05.880 --> 00:03:08.800 align:middle
小さな整数 1 に
class メッセージを送ります。

00:03:08.960 --> 00:03:12.760 align:middle
SmallInteger が返ってきます。
1 は整数ですから。正しいです。

00:03:13.560 --> 00:03:18.840 align:middle
1 class の結果である SmallInteger に
maxVal メッセージを送ります。

00:03:19.000 --> 00:03:20.800 align:middle
maxVal メッセージとは何でしょう？

00:03:20.960 --> 00:03:25.560 align:middle
「あなた(SmallInteger)が符号化できる
最大の数は何ですか？」という意味です。

00:03:25.720 --> 00:03:29.960 align:middle
この大きな数が得られます。
この、最後が23で終わる数です。

00:03:30.960 --> 00:03:36.120 align:middle
この数に + 1 メッセージを送ります。

00:03:36.920 --> 00:03:40.160 align:middle
返ってくるのは小さな整数(SmallInteger)
ではありません。

00:03:40.320 --> 00:03:44.240 align:middle
なぜなら、SmallIntegerで表現できる
最大の数がこれだからです。

00:03:44.400 --> 00:03:47.080 align:middle
結果として
答えはSmallIntegerにはできません。

00:03:47.240 --> 00:03:51.440 align:middle
この数のクラスが何かを知りたいです。

00:03:51.960 --> 00:03:56.480 align:middle
括弧で囲んで、class を送ります。
LargePositiveInteger が返ってきます。

00:03:56.640 --> 00:04:00.160 align:middle
これが最大のSmallIntegerで

00:04:00.320 --> 00:04:02.840 align:middle
これが最小のLargePositiveIntegerです。

00:04:04.280 --> 00:04:06.280 align:middle
括弧で囲むのは

00:04:06.440 --> 00:04:09.480 align:middle
それがないと
class は 1 に送られてしまうからです。

00:04:09.640 --> 00:04:12.760 align:middle
それでは困ります。
結果に対して class を送りたいのです。

00:04:14.520 --> 00:04:18.640 align:middle
矩形を生成したとします。

00:04:18.800 --> 00:04:22.120 align:middle
その矩形の右下の点が欲しい時に

00:04:22.280 --> 00:04:24.640 align:middle
こう書くと
実行するとクラッシュします。

00:04:24.800 --> 00:04:29.080 align:middle
システムは理解できません。
100 は bottomRight を理解できません。

00:04:29.240 --> 00:04:33.680 align:middle
なぜ？
bottomRightは単項メッセージなので

00:04:33.840 --> 00:04:38.560 align:middle
他のメッセージよりも先に実行されます。
bottomRightはレシーバーである100に送られます。

00:04:38.720 --> 00:04:42.520 align:middle
100 はこの API を理解できません。
なぜなら 100 は Rectangle(矩形)ではないからです。

00:04:42.680 --> 00:04:46.360 align:middle
この表現式のように
括弧で囲まなければなりません。

00:04:46.520 --> 00:04:50.440 align:middle
どのように動くのでしょう？
括弧で囲まれたものが先に実行されます。

00:04:50.600 --> 00:04:55.880 align:middle
内側では2つの二項メッセージがあり
それらが実行されます。

00:04:56.040 --> 00:04:58.960 align:middle
2つの点が生成されます。

00:04:59.120 --> 00:05:02.360 align:middle
そして extent: メッセージを送ります。
矩形を作る一方の点に送ります。

00:05:02.520 --> 00:05:05.120 align:middle
点 0@0 があります。

00:05:05.280 --> 00:05:09.880 align:middle
extent:メッセージに広がり 100@100 を渡します。

00:05:10.440 --> 00:05:12.080 align:middle
この矩形が返ってきます。

00:05:12.240 --> 00:05:15.680 align:middle
それに bottomRight の値を尋ねます。

00:05:15.840 --> 00:05:17.200 align:middle
矩形の

00:05:17.360 --> 00:05:20.480 align:middle
ここの点の値を返してきます。

00:05:20.640 --> 00:05:23.400 align:middle
100@100 です。

00:05:24.960 --> 00:05:28.600 align:middle
Pharo では色々な事がシンプルだと
これまで言ってきました。

00:05:28.760 --> 00:05:30.360 align:middle
メッセージしかありません。

00:05:30.520 --> 00:05:34.560 align:middle
+ はメッセージです。他と同様。
優先順位はありません。

00:05:34.720 --> 00:05:38.400 align:middle
+ をDSL(ドメイン特化言語)に使えるのは
良いことです。

00:05:38.560 --> 00:05:42.920 align:middle
+ を数学的なオブジェクトとは関係ない
オブジェクト間に使うことができます。

00:05:43.080 --> 00:05:47.200 align:middle
Java ではこれはできません。
C++ では演算子を再定義することで可能です。

00:05:47.360 --> 00:05:49.760 align:middle
Pharo では

00:05:49.920 --> 00:05:53.200 align:middle
+ は他のメッセージと同じ扱いにすると
決めることで解決しています。

00:05:53.360 --> 00:05:55.280 align:middle
強調すべきはシンプルさです。

00:05:55.440 --> 00:05:58.880 align:middle
代償があります。
数学的な結合順位がありません。

00:05:59.040 --> 00:06:00.960 align:middle
例を見てみましょう。

00:06:02.160 --> 00:06:05.640 align:middle
この表現式では
2つの演算子があります。

00:06:05.800 --> 00:06:08.480 align:middle
2つの二項メッセージです。

00:06:08.640 --> 00:06:10.560 align:middle
左から右に実行されます。

00:06:11.720 --> 00:06:15.480 align:middle
5 が得られ、50が返ってきます。
学校で習ったのとは違います。

00:06:15.640 --> 00:06:19.440 align:middle
これを解決するためには
括弧で囲む必要があります。

00:06:19.600 --> 00:06:21.200 align:middle
* を括弧で囲みます。

00:06:21.360 --> 00:06:26.400 align:middle
Pharo で算術演算子を使う時には
注意が必要です。

00:06:26.560 --> 00:06:29.520 align:middle
数学的演算子はメッセージにすぎないからです。

00:06:30.040 --> 00:06:31.160 align:middle
もう1つの例です。

00:06:31.320 --> 00:06:34.800 align:middle
1/3 + 2/3 と書くと
正しい答えが得られません。

00:06:34.960 --> 00:06:38.640 align:middle
システムがこの式を先に実行するからです。

00:06:39.160 --> 00:06:41.120 align:middle
左から右へ実行されるからです。

00:06:41.280 --> 00:06:43.840 align:middle
括弧で囲むと
正しい結果が得られます。

00:06:44.000 --> 00:06:46.640 align:middle
興味深い点を1つ挙げると

00:06:46.800 --> 00:06:49.960 align:middle
(1/3) + (2/3) と書くと
整数の 1 が得られます。

00:06:50.120 --> 00:06:54.280 align:middle
1.000... や 0.999... ではありません。

00:06:54.440 --> 00:06:59.440 align:middle
正確な分数の操作を行います。
正確な計算結果が得られます。

00:06:59.600 --> 00:07:01.200 align:middle
まとめると

00:07:01.360 --> 00:07:05.600 align:middle
メッセージには3種類あります。
もう知っている筈です。

00:07:05.760 --> 00:07:07.560 align:middle
単項、二項、そしてキーワードです。

00:07:07.720 --> 00:07:11.040 align:middle
まず最初に括弧が実行されます。

00:07:11.200 --> 00:07:13.320 align:middle
そして単項、二項、そしてキーワードです。

00:07:13.480 --> 00:07:16.120 align:middle
同じレベルの場合には

00:07:16.280 --> 00:07:20.480 align:middle
例えば2つの単項メッセージがある場合には
左から右に進みます。

00:07:20.640 --> 00:07:23.320 align:middle
数学的な結合順位はありません。

00:07:23.480 --> 00:07:26.480 align:middle
数学的な演算子も単なるメッセージです。

00:07:26.640 --> 00:07:29.280 align:middle
多くの言語と異なるのは

00:07:29.440 --> 00:07:34.160 align:middle
引数がメッセージの構造の中に置かれることです。
例えば between:and: です。

