1 00:00:00,520 --> 00:00:03,880 In this session, we'll study message composition. 2 00:00:04,040 --> 00:00:08,720 We'll see how precedence works: the hierarchy of items. 3 00:00:08,880 --> 00:00:11,600 The question that need to be asked is: 4 00:00:11,760 --> 00:00:15,080 "What happens when you have a sequence of unary messages?" 5 00:00:15,240 --> 00:00:18,040 I wrote the following expression: 6 00:00:18,200 --> 00:00:20,720 1000 factorial class name What happens? 7 00:00:20,880 --> 00:00:24,400 You execute it as if I had written all these parentheses. 8 00:00:24,560 --> 00:00:26,680 You can see they're annoying. 9 00:00:26,840 --> 00:00:30,840 When you have messages at the same level 10 00:00:31,000 --> 00:00:35,000 (unary, binary, or keywords: it works with all three), 11 00:00:35,160 --> 00:00:37,320 it evaluates them from left to right. 12 00:00:37,480 --> 00:00:40,280 I send the message factorial to 1000. 13 00:00:40,440 --> 00:00:43,960 Then I send the message class to the result of factorial. 14 00:00:44,120 --> 00:00:46,600 Then I send the message name 15 00:00:47,800 --> 00:00:50,600 to this new object. 16 00:00:50,760 --> 00:00:52,880 It returns LargePositiveInteger. 17 00:00:53,640 --> 00:00:56,080 Factorial 1000 is a large number. 18 00:00:56,240 --> 00:00:59,320 You can also try with factorial 10000. 19 00:00:59,920 --> 00:01:01,160 It's a bit longer. 20 00:01:02,160 --> 00:01:06,160 There are messages with parentheses 21 00:01:06,320 --> 00:01:08,520 when they need to be executed first. 22 00:01:08,680 --> 00:01:11,960 Then you have unary messages, then binary, then keywords. 23 00:01:12,120 --> 00:01:15,200 When at the same level, you go from left to right. 24 00:01:15,920 --> 00:01:17,720 Let's take one example. 25 00:01:17,880 --> 00:01:21,800 I have an unary message, squared, 26 00:01:21,960 --> 00:01:24,480 and a binary message, +. 27 00:01:24,640 --> 00:01:27,000 The unary message wins. 28 00:01:27,160 --> 00:01:30,800 First, I send squared. 29 00:01:30,960 --> 00:01:33,760 Next, I send the message +. 30 00:01:33,920 --> 00:01:36,640 It returns 11. It's right. 31 00:01:37,480 --> 00:01:39,560 This is another situation. 32 00:01:39,720 --> 00:01:42,360 I'm going to raise to the power using raisedTo. 33 00:01:42,520 --> 00:01:47,040 I have a binary message and a keyword. The binary message wins. 34 00:01:47,200 --> 00:01:49,520 First, I get 5. 35 00:01:49,680 --> 00:01:53,080 Then I execute raisedTo, it returns 32. It's right. 36 00:01:54,000 --> 00:01:56,160 This is a more complicated example. 37 00:01:56,320 --> 00:02:00,120 Colors in Pharo are objects. 38 00:02:00,280 --> 00:02:01,680 I have the class Color. 39 00:02:01,840 --> 00:02:06,240 I have three unary messages: gray, white, and black. 40 00:02:06,400 --> 00:02:11,360 I have two binary messages: = and -. 41 00:02:11,520 --> 00:02:16,160 What happens then? The system first executes every unary message. 42 00:02:16,840 --> 00:02:21,320 It returns the color aGray, the color aWhite, and the color aBlack. 43 00:02:21,480 --> 00:02:25,080 Now I have to send messages. 44 00:02:25,240 --> 00:02:28,560 I have to choose between the message - and the message =. 45 00:02:29,520 --> 00:02:34,480 I send the message - to the object aGray with white as an argument. 46 00:02:34,640 --> 00:02:36,800 It returns the color aBlack. 47 00:02:37,520 --> 00:02:41,520 I compare the two colors. I get aBlack = aBlack, which is true. 48 00:02:43,320 --> 00:02:46,160 This is an example to show you 49 00:02:47,360 --> 00:02:50,200 you can also do automatic conversion with Pharo. 50 00:02:50,360 --> 00:02:52,880 It's some sort of joke. 51 00:02:53,960 --> 00:02:57,960 I have the expression 1 class maxVal + 1 52 00:02:58,120 --> 00:03:00,920 I have two unary messages, class and maxVal, 53 00:03:01,080 --> 00:03:02,400 and one binary message. 54 00:03:03,640 --> 00:03:05,720 How is this expression executed? 55 00:03:05,880 --> 00:03:08,800 I send the message class to the small integer 1. 56 00:03:08,960 --> 00:03:12,760 It returns SmallInteger since 1 is an integer. It works. 57 00:03:13,560 --> 00:03:18,840 Since it's the result of 1 class, I send it the message maxVal. 58 00:03:19,000 --> 00:03:20,800 What is the message maxVal? 59 00:03:20,960 --> 00:03:25,560 It means: "What is the largest number you can encode over a small integer?" 60 00:03:25,720 --> 00:03:29,960 I get this large number which ends with 23. 61 00:03:30,960 --> 00:03:36,120 To this number, I send the message + 1. 62 00:03:36,920 --> 00:03:40,160 It doesn't return a small integer 63 00:03:40,320 --> 00:03:44,240 since this is the value that can be represented by a small integer. 64 00:03:44,400 --> 00:03:47,080 As a result, it can't be a small integer. 65 00:03:47,240 --> 00:03:51,440 I want to know what the class of this number is. 66 00:03:51,960 --> 00:03:56,480 I write parentheses and I send class. It returns LargePositiveInteger. 67 00:03:56,640 --> 00:04:00,160 This is the largest of small integers. 68 00:04:00,320 --> 00:04:02,840 And that's the smallest of large integers. 69 00:04:04,280 --> 00:04:06,280 I wrote parentheses 70 00:04:06,440 --> 00:04:09,480 because without them, class would have been sent to 1. 71 00:04:09,640 --> 00:04:12,760 I don't want that: I want to send class to the result. 72 00:04:14,520 --> 00:04:18,640 Imagine that I created a rectangle. 73 00:04:18,800 --> 00:04:22,120 I want to get the point on the bottom right of the rectangle. 74 00:04:22,280 --> 00:04:24,640 I wrote this. It crashes when I execute it. 75 00:04:24,800 --> 00:04:29,080 The system doesn't understand: 100 does not understand bottomRight 76 00:04:29,240 --> 00:04:33,680 Why? Because bottomRight is a unary message. 77 00:04:33,840 --> 00:04:38,560 It gets executed before the others: it is sent to 100, its receiver. 78 00:04:38,720 --> 00:04:42,520 100 can't understand this API as it is that of the class Rectangle. 79 00:04:42,680 --> 00:04:46,360 I have to write parentheses as I did in this expression. 80 00:04:46,520 --> 00:04:50,440 How does it work? What's between parentheses is executed first. 81 00:04:50,600 --> 00:04:55,880 Inside, I have two binary messages which are executed. 82 00:04:56,040 --> 00:04:58,960 They create points: two of them get created. 83 00:04:59,120 --> 00:05:02,360 I send extent: to a point which creates a rectangle. 84 00:05:02,520 --> 00:05:05,120 I have a point 0@0. 85 00:05:05,280 --> 00:05:09,880 I pass it extent 100@100. 86 00:05:10,440 --> 00:05:12,080 It returns this rectangle. 87 00:05:12,240 --> 00:05:15,680 I query it for the value bottomRight. 88 00:05:15,840 --> 00:05:17,200 I get a rectangle. 89 00:05:17,360 --> 00:05:20,480 It returns the value of the point here: 90 00:05:20,640 --> 00:05:23,400 it is 100@100. 91 00:05:24,960 --> 00:05:28,600 I told you things were very simple in Pharo: 92 00:05:28,760 --> 00:05:30,360 there are only messages. 93 00:05:30,520 --> 00:05:34,560 + is a message like any other. There's no order of precedence. 94 00:05:34,720 --> 00:05:38,400 What's nice is that you can use + for domain specific languages. 95 00:05:38,560 --> 00:05:42,920 You can use + between objects unrelated to mathematical objects. 96 00:05:43,080 --> 00:05:47,200 You can't do it in Java. You can do it in C++ by redefining operators. 97 00:05:47,360 --> 00:05:49,760 In Pharo, the solution 98 00:05:49,920 --> 00:05:53,200 was to decide + would be like any other message. 99 00:05:53,360 --> 00:05:55,280 Emphasis was put on simplicity. 100 00:05:55,440 --> 00:05:58,880 There's a price to pay: there's no mathematical precedence. 101 00:05:59,040 --> 00:06:00,960 Let's see this with an example. 102 00:06:02,160 --> 00:06:05,640 In this expression, there are two operators: 103 00:06:05,800 --> 00:06:08,480 two binary messages. 104 00:06:08,640 --> 00:06:10,560 I execute from left to right. 105 00:06:11,720 --> 00:06:15,480 I get 5 and it returns 50: it's not what I learned in school. 106 00:06:15,640 --> 00:06:19,440 To disambiguate this, I have to rewrite this using parentheses 107 00:06:19,600 --> 00:06:21,200 around *. 108 00:06:21,360 --> 00:06:26,400 You have to be careful when using arithmetic operations in Pharo 109 00:06:26,560 --> 00:06:29,520 since mathematical operators are just messages. 110 00:06:30,040 --> 00:06:31,160 Another example: 111 00:06:31,320 --> 00:06:34,800 if I write 1/3 + 2/3, I don't get the right result 112 00:06:34,960 --> 00:06:38,640 as the system first executes this expression 113 00:06:39,160 --> 00:06:41,120 since it goes from left to right. 114 00:06:41,280 --> 00:06:43,840 If I add parentheses, I get the right result. 115 00:06:44,000 --> 00:06:46,640 I have an interesting point to make: 116 00:06:46,800 --> 00:06:49,960 when I write 1/3 + 2/3, I get the small integer 1. 117 00:06:50,120 --> 00:06:54,280 I don't get 1.000... or 0.999... 118 00:06:54,440 --> 00:06:59,440 I manipulate exact fractions. I get exact calculations. 119 00:06:59,600 --> 00:07:01,200 To sum up, 120 00:07:01,360 --> 00:07:05,600 there are three types of messages, which you should know by now: 121 00:07:05,760 --> 00:07:07,560 unary, binary, keywords. 122 00:07:07,720 --> 00:07:11,040 You first execute parentheses, 123 00:07:11,200 --> 00:07:13,320 then unary, binary, and keywords. 124 00:07:13,480 --> 00:07:16,120 When at the same level, 125 00:07:16,280 --> 00:07:20,480 for instance with two unary messages, you go from left to right. 126 00:07:20,640 --> 00:07:23,320 There's no mathematical precedence 127 00:07:23,480 --> 00:07:26,480 as mathematical operations are plain messages. 128 00:07:26,640 --> 00:07:29,280 What's different from most languages: 129 00:07:29,440 --> 00:07:34,160 arguments are placed inside the message structure. between: and: for instance.