summaryrefslogblamecommitdiffstats
path: root/2021/captions/form.md
blob: 76984b283e7b2a79d3060d80af4f97d76543c8f0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430













































































































































































































































































































































































































































                                                                                                                                     
<a name="transcript"></a>
# Transcript

[[!template text="My name is Ian Eure," start="00:00:01.199" video="mainVideo" id=subtitle]]
[[!template text="and welcome to my talk" start="00:00:02.320" video="mainVideo" id=subtitle]]
[[!template text="&quot;Old McCarthy Had a Form&quot;." start="00:00:03.199" video="mainVideo" id=subtitle]]
[[!template text="In this talk," start="00:00:05.120" video="mainVideo" id=subtitle]]
[[!template text="I'm going to be discussing EIEIO," start="00:00:05.759" video="mainVideo" id=subtitle]]
[[!template text="which is an Emacs Lisp implementation" start="00:00:07.759" video="mainVideo" id=subtitle]]
[[!template text="of the Common Lisp object system." start="00:00:09.920" video="mainVideo" id=subtitle]]
[[!template text="CLOS is a way of writing" start="00:00:12.320" video="mainVideo" id=subtitle]]
[[!template text="object-oriented Common Lisp code," start="00:00:13.519" video="mainVideo" id=subtitle]]
[[!template text="and with EIEIO you have much of that same" start="00:00:15.360" video="mainVideo" id=subtitle]]
[[!template text="power but inside Emacs." start="00:00:17.920" video="mainVideo" id=subtitle]]
[[!template text="I'm going to be using those two names" start="00:00:19.920" video="mainVideo" id=subtitle]]
[[!template text="interchangeably throughout this talk," start="00:00:21.359" video="mainVideo" id=subtitle]]
[[!template text="since they're nearly equivalent." start="00:00:22.988" video="mainVideo" id=subtitle]]
[[!template text="You might wonder," start="00:00:26.640" video="mainVideo" id=subtitle]]
[[!template text="&quot;Why would I want to write" start="00:00:27.534" video="mainVideo" id=subtitle]]
[[!template text="object Emacs Lisp code?&quot;." start="00:00:28.880" video="mainVideo" id=subtitle]]
[[!template text="I like it because I like writing" start="00:00:31.439" video="mainVideo" id=subtitle]]
[[!template text="in a functional programming style," start="00:00:33.440" video="mainVideo" id=subtitle]]
[[!template text="or I like to do an imperative style" start="00:00:34.960" video="mainVideo" id=subtitle]]
[[!template text="that captures interactive key sequences" start="00:00:36.896" video="mainVideo" id=subtitle]]
[[!template text="that I might enter manually." start="00:00:39.040" video="mainVideo" id=subtitle]]
[[!template text="Well, I think, different kinds of programs" start="00:00:41.200" video="mainVideo" id=subtitle]]
[[!template text="need different kind of programming paradigms," start="00:00:42.800" video="mainVideo" id=subtitle]]
[[!template text="and sometimes OOP is the one that fits." start="00:00:45.120" video="mainVideo" id=subtitle]]
[[!template text="Also, if you've done much OOP before," start="00:00:47.760" video="mainVideo" id=subtitle]]
[[!template text="you might be surprised by" start="00:00:49.708" video="mainVideo" id=subtitle]]
[[!template text="how EIEIO works and the sorts of power" start="00:00:50.655" video="mainVideo" id=subtitle]]
[[!template text="that it brings to your programs." start="00:00:52.879" video="mainVideo" id=subtitle]]
[[!template text="So, let's talk about that model now." start="00:00:55.039" video="mainVideo" id=subtitle]]
[[!template text="Classes are pretty much what" start="00:00:58.480" video="mainVideo" id=subtitle]]
[[!template text="you would expect if you've done" start="00:01:00.000" video="mainVideo" id=subtitle]]
[[!template text="OOP programming before." start="00:01:01.120" video="mainVideo" id=subtitle]]
[[!template text="In the CLOS model," start="00:01:02.879" video="mainVideo" id=subtitle]]
[[!template text="they only have fields," start="00:01:04.400" video="mainVideo" id=subtitle]]
[[!template text="they only encapsulate values," start="00:01:06.400" video="mainVideo" id=subtitle]]
[[!template text="they don't have anything to do with methods." start="00:01:08.000" video="mainVideo" id=subtitle]]
[[!template text="So, in this case, we have a base class for" start="00:01:10.720" video="mainVideo" id=subtitle]]
[[!template text="an EMMS player backend," start="00:01:13.040" video="mainVideo" id=subtitle]]
[[!template text="and it has one field (a slot is what" start="00:01:15.040" video="mainVideo" id=subtitle]]
[[!template text="it's called in CLOS terminology)," start="00:01:18.159" video="mainVideo" id=subtitle]]
[[!template text="which indicates whether it's playing or not," start="00:01:20.000" video="mainVideo" id=subtitle]]
[[!template text="and it's declared abstract," start="00:01:22.720" video="mainVideo" id=subtitle]]
[[!template text="so you can't create an instance" start="00:01:24.080" video="mainVideo" id=subtitle]]
[[!template text="of an object based on this class," start="00:01:25.439" video="mainVideo" id=subtitle]]
[[!template text="you can only extend it with another class," start="00:01:27.040" video="mainVideo" id=subtitle]]
[[!template text="that's an EIEIO extension," start="00:01:29.280" video="mainVideo" id=subtitle]]
[[!template text="but I think it's a pretty good one." start="00:01:31.119" video="mainVideo" id=subtitle]]
[[!template text="You can also see there's a class" start="00:01:33.439" video="mainVideo" id=subtitle]]
[[!template text="that implements an mpv player back-end," start="00:01:34.640" video="mainVideo" id=subtitle]]
[[!template text="and it extends the base class," start="00:01:37.119" video="mainVideo" id=subtitle]]
[[!template text="it doesn't add any slots," start="00:01:39.680" video="mainVideo" id=subtitle]]
[[!template text="and those get inherited from the base class." start="00:01:40.960" video="mainVideo" id=subtitle]]
[[!template text="If you want these to do much more" start="00:01:44.479" video="mainVideo" id=subtitle]]
[[!template text="than encapsulate data," start="00:01:45.936" video="mainVideo" id=subtitle]]
[[!template text="you need to start writing methods." start="00:01:46.960" video="mainVideo" id=subtitle]]
[[!template text="The CLOS model is to have" start="00:01:48.880" video="mainVideo" id=subtitle]]
[[!template text="a generic function." start="00:01:50.324" video="mainVideo" id=subtitle]]
[[!template text="A generic function is" start="00:01:51.439" video="mainVideo" id=subtitle]]
[[!template text="kind of like an interface," start="00:01:52.399" video="mainVideo" id=subtitle]]
[[!template text="it's just a name and an argument list," start="00:01:53.680" video="mainVideo" id=subtitle]]
[[!template text="and there's no implementation," start="00:01:55.600" video="mainVideo" id=subtitle]]
[[!template text="you have to write a method" start="00:01:57.280" video="mainVideo" id=subtitle]]
[[!template text="in order to have an actual implementation." start="00:01:58.560" video="mainVideo" id=subtitle]]
[[!template text="When you call the generic function," start="00:02:00.960" video="mainVideo" id=subtitle]]
[[!template text="the system will do a dynamic dispatch" start="00:02:02.880" video="mainVideo" id=subtitle]]
[[!template text="to a method that matches based on" start="00:02:04.960" video="mainVideo" id=subtitle]]
[[!template text="its argument types and how the method" start="00:02:06.560" video="mainVideo" id=subtitle]]
[[!template text="has declared that it should be invoked." start="00:02:08.319" video="mainVideo" id=subtitle]]
[[!template text="Here's an example of some methods" start="00:02:12.239" video="mainVideo" id=subtitle]]
[[!template text="for our mpv player backend," start="00:02:14.239" video="mainVideo" id=subtitle]]
[[!template text="you can see that it'll play anything" start="00:02:16.480" video="mainVideo" id=subtitle]]
[[!template text="other than something" start="00:02:19.599" video="mainVideo" id=subtitle]]
[[!template text="with a keyword of `unplayable`," start="00:02:21.200" video="mainVideo" id=subtitle]]
[[!template text="and it just has dummy start and stop methods" start="00:02:23.200" video="mainVideo" id=subtitle]]
[[!template text="that return &quot;Started&quot; and &quot;Stopped&quot; text." start="00:02:25.328" video="mainVideo" id=subtitle]]
[[!template text="A method is just one implementation" start="00:02:27.680" video="mainVideo" id=subtitle]]
[[!template text="of a generic function," start="00:02:29.599" video="mainVideo" id=subtitle]]
[[!template text="and you can have as many as you need." start="00:02:30.552" video="mainVideo" id=subtitle]]
[[!template text="In order to determine" start="00:02:32.640" video="mainVideo" id=subtitle]]
[[!template text="which method gets dispatched" start="00:02:33.920" video="mainVideo" id=subtitle]]
[[!template text="when you call a generic function," start="00:02:35.519" video="mainVideo" id=subtitle]]
[[!template text="they're specialized based on" start="00:02:36.879" video="mainVideo" id=subtitle]]
[[!template text="their argument type." start="00:02:38.080" video="mainVideo" id=subtitle]]
[[!template text="In this case, you can see that" start="00:02:39.360" video="mainVideo" id=subtitle]]
[[!template text="first argument says" start="00:02:40.640" video="mainVideo" id=subtitle]]
[[!template text="`player talk/emms-player-mpv`," start="00:02:41.680" video="mainVideo" id=subtitle]]
[[!template text="that means that if that first argument" start="00:02:44.480" video="mainVideo" id=subtitle]]
[[!template text="is an instance of the mpv player" start="00:02:46.239" video="mainVideo" id=subtitle]]
[[!template text="or a subclass of it," start="00:02:48.480" video="mainVideo" id=subtitle]]
[[!template text="then those methods will be invoked," start="00:02:50.080" video="mainVideo" id=subtitle]]
[[!template text="unless there's a more specific one" start="00:02:52.000" video="mainVideo" id=subtitle]]
[[!template text="based on that argument type." start="00:02:53.560" video="mainVideo" id=subtitle]]
[[!template text="You don't have to define" start="00:02:55.440" video="mainVideo" id=subtitle]]
[[!template text="the generic functions." start="00:02:56.656" video="mainVideo" id=subtitle]]
[[!template text="If you define a method," start="00:02:57.760" video="mainVideo" id=subtitle]]
[[!template text="then it'll implicitly define" start="00:02:59.040" video="mainVideo" id=subtitle]]
[[!template text="the generic function for you." start="00:03:00.451" video="mainVideo" id=subtitle]]
[[!template text="Specialization is really powerful." start="00:03:03.599" video="mainVideo" id=subtitle]]
[[!template text="It lets the methods define" start="00:03:05.440" video="mainVideo" id=subtitle]]
[[!template text="how they get invoked" start="00:03:06.939" video="mainVideo" id=subtitle]]
[[!template text="If you've done much programming in Clojure," start="00:03:08.400" video="mainVideo" id=subtitle]]
[[!template text="this sounds a little bit like multi-methods," start="00:03:10.472" video="mainVideo" id=subtitle]]
[[!template text="but with multi-methods, only the main method," start="00:03:12.959" video="mainVideo" id=subtitle]]
[[!template text="the equivalent of the generic function," start="00:03:16.319" video="mainVideo" id=subtitle]]
[[!template text="can determine how they're dispatched." start="00:03:18.000" video="mainVideo" id=subtitle]]
[[!template text="So, as the writer of an interface," start="00:03:19.920" video="mainVideo" id=subtitle]]
[[!template text="you might not be able to foresee" start="00:03:21.519" video="mainVideo" id=subtitle]]
[[!template text="every way that someone who's implementing" start="00:03:23.120" video="mainVideo" id=subtitle]]
[[!template text="a version of that interface" start="00:03:25.519" video="mainVideo" id=subtitle]]
[[!template text="would like to dispatch." start="00:03:26.959" video="mainVideo" id=subtitle]]
[[!template text="CLOS doesn't have that problem," start="00:03:28.400" video="mainVideo" id=subtitle]]
[[!template text="you get to define your" start="00:03:29.920" video="mainVideo" id=subtitle]]
[[!template text="own invocation semantics." start="00:03:31.200" video="mainVideo" id=subtitle]]
[[!template text="You're also not limited to" start="00:03:34.080" video="mainVideo" id=subtitle]]
[[!template text="dispatching based on the value" start="00:03:35.360" video="mainVideo" id=subtitle]]
[[!template text="being a subclass of an EIEIO type." start="00:03:37.200" video="mainVideo" id=subtitle]]
[[!template text="You can dispatch based on" start="00:03:39.920" video="mainVideo" id=subtitle]]
[[!template text="a primitive type like integer," start="00:03:41.280" video="mainVideo" id=subtitle]]
[[!template text="you can dispatch based on the value," start="00:03:42.879" video="mainVideo" id=subtitle]]
[[!template text="you can dispatch on multiple arguments," start="00:03:45.360" video="mainVideo" id=subtitle]]
[[!template text="and there's also a default dispatch" start="00:03:47.599" video="mainVideo" id=subtitle]]
[[!template text="that will get applied" start="00:03:49.599" video="mainVideo" id=subtitle]]
[[!template text="if there's no others that are defined." start="00:03:50.688" video="mainVideo" id=subtitle]]
[[!template text="If you don't have a default," start="00:03:53.200" video="mainVideo" id=subtitle]]
[[!template text="then you'll just get an error" start="00:03:54.319" video="mainVideo" id=subtitle]]
[[!template text="from the system," start="00:03:55.439" video="mainVideo" id=subtitle]]
[[!template text="and if that doesn't cover it," start="00:03:56.480" video="mainVideo" id=subtitle]]
[[!template text="you can even define your own." start="00:03:57.439" video="mainVideo" id=subtitle]]
[[!template text="Definition is with the" start="00:03:59.040" video="mainVideo" id=subtitle]]
[[!template text="`cl-generic-generalizers`," start="00:04:00.239" video="mainVideo" id=subtitle]]
[[!template text="which is itself a generic function." start="00:04:01.760" video="mainVideo" id=subtitle]]
[[!template text="Much of CLOS is built in CLOS," start="00:04:03.680" video="mainVideo" id=subtitle]]
[[!template text="which I think is really cool." start="00:04:05.680" video="mainVideo" id=subtitle]]
[[!template text="In addition to all that," start="00:04:08.319" video="mainVideo" id=subtitle]]
[[!template text="you have four different types of methods," start="00:04:09.599" video="mainVideo" id=subtitle]]
[[!template text="and those are distinguished by" start="00:04:12.319" video="mainVideo" id=subtitle]]
[[!template text="what's called a qualifier." start="00:04:13.680" video="mainVideo" id=subtitle]]
[[!template text="Every function can have methods" start="00:04:16.000" video="mainVideo" id=subtitle]]
[[!template text="that have all four different" start="00:04:18.400" video="mainVideo" id=subtitle]]
[[!template text="types of qualifiers," start="00:04:20.239" video="mainVideo" id=subtitle]]
[[!template text="and based on your class inheritance," start="00:04:21.280" video="mainVideo" id=subtitle]]
[[!template text="you might have multiple of each type." start="00:04:22.960" video="mainVideo" id=subtitle]]
[[!template text="There's the primary method," start="00:04:25.680" video="mainVideo" id=subtitle]]
[[!template text="which is equivalent to the method" start="00:04:26.800" video="mainVideo" id=subtitle]]
[[!template text="in any other OOP system," start="00:04:28.560" video="mainVideo" id=subtitle]]
[[!template text="so we're not going to cover that too much." start="00:04:29.919" video="mainVideo" id=subtitle]]
[[!template text="Then there's a `before` method." start="00:04:32.160" video="mainVideo" id=subtitle]]
[[!template text="This is evaluated before" start="00:04:33.759" video="mainVideo" id=subtitle]]
[[!template text="the primary method for side effects," start="00:04:35.600" video="mainVideo" id=subtitle]]
[[!template text="and its return value is discarded." start="00:04:37.440" video="mainVideo" id=subtitle]]
[[!template text="There's an `after` method," start="00:04:40.080" video="mainVideo" id=subtitle]]
[[!template text="which is the same but happens after" start="00:04:41.120" video="mainVideo" id=subtitle]]
[[!template text="the method has finished evaluating." start="00:04:42.560" video="mainVideo" id=subtitle]]
[[!template text="And then there's an `around` method" start="00:04:44.479" video="mainVideo" id=subtitle]]
[[!template text="that happens around all the other three." start="00:04:46.639" video="mainVideo" id=subtitle]]
[[!template text="And by using these types of methods" start="00:04:49.199" video="mainVideo" id=subtitle]]
[[!template text="and using class inheritance" start="00:04:51.120" video="mainVideo" id=subtitle]]
[[!template text="to compose them into your classes," start="00:04:52.560" video="mainVideo" id=subtitle]]
[[!template text="you can add some really powerful" start="00:04:54.560" video="mainVideo" id=subtitle]]
[[!template text="mixin type functionality." start="00:04:56.479" video="mainVideo" id=subtitle]]
[[!template text="You can use before and after" start="00:04:58.240" video="mainVideo" id=subtitle]]
[[!template text="to build things like logging," start="00:04:59.764" video="mainVideo" id=subtitle]]
[[!template text="and you can use around" start="00:05:01.280" video="mainVideo" id=subtitle]]
[[!template text="to implement things like memoization." start="00:05:02.479" video="mainVideo" id=subtitle]]
[[!template text="If you've done much Emacs Lisp programming," start="00:05:04.880" video="mainVideo" id=subtitle]]
[[!template text="those before after and around" start="00:05:06.720" video="mainVideo" id=subtitle]]
[[!template text="might jog your memory because" start="00:05:08.160" video="mainVideo" id=subtitle]]
[[!template text="they're the same features you get" start="00:05:09.919" video="mainVideo" id=subtitle]]
[[!template text="with Emacs's built-in function advice." start="00:05:11.440" video="mainVideo" id=subtitle]]
[[!template text="The thing with function advice is that" start="00:05:14.160" video="mainVideo" id=subtitle]]
[[!template text="it only works on functions" start="00:05:15.680" video="mainVideo" id=subtitle]]
[[!template text="in the global namespace," start="00:05:17.199" video="mainVideo" id=subtitle]]
[[!template text="and there's no kind of conditionality," start="00:05:18.240" video="mainVideo" id=subtitle]]
[[!template text="they always get dispatched" start="00:05:20.360" video="mainVideo" id=subtitle]]
[[!template text="when that function is invoked." start="00:05:21.840" video="mainVideo" id=subtitle]]
[[!template text="The nice thing about the CLOS system is that" start="00:05:23.440" video="mainVideo" id=subtitle]]
[[!template text="whether they get invoked or not" start="00:05:25.600" video="mainVideo" id=subtitle]]
[[!template text="depends on whether they exist in" start="00:05:27.039" video="mainVideo" id=subtitle]]
[[!template text="the class hierarchy," start="00:05:28.872" video="mainVideo" id=subtitle]]
[[!template text="so you can add them to your" start="00:05:30.160" video="mainVideo" id=subtitle]]
[[!template text="class hierarchy if you want" start="00:05:31.520" video="mainVideo" id=subtitle]]
[[!template text="that extra functionality" start="00:05:32.880" video="mainVideo" id=subtitle]]
[[!template text="like logging or memoization," start="00:05:34.000" video="mainVideo" id=subtitle]]
[[!template text="and you can exclude it if you don't." start="00:05:35.440" video="mainVideo" id=subtitle]]
[[!template text="I think that's really powerful" start="00:05:37.120" video="mainVideo" id=subtitle]]
[[!template text="and a very interesting way of doing it." start="00:05:38.320" video="mainVideo" id=subtitle]]
[[!template text="It also supports multiple inheritance," start="00:05:42.639" video="mainVideo" id=subtitle]]
[[!template text="which is the mechanism that you can use" start="00:05:44.639" video="mainVideo" id=subtitle]]
[[!template text="to compose all these different kinds of" start="00:05:46.639" video="mainVideo" id=subtitle]]
[[!template text="behaviors into a single object that does" start="00:05:48.560" video="mainVideo" id=subtitle]]
[[!template text="all the things that you want." start="00:05:50.479" video="mainVideo" id=subtitle]]
[[!template text="Here's a quick example of a logger." start="00:05:52.240" video="mainVideo" id=subtitle]]
[[!template text="So, you can see the class just has" start="00:05:54.720" video="mainVideo" id=subtitle]]
[[!template text="a single slot called `messages`," start="00:05:56.240" video="mainVideo" id=subtitle]]
[[!template text="it has a `log` method" start="00:05:58.319" video="mainVideo" id=subtitle]]
[[!template text="that pushes a new message," start="00:05:59.840" video="mainVideo" id=subtitle]]
[[!template text="which is a format string, into that," start="00:06:01.440" video="mainVideo" id=subtitle]]
[[!template text="and then it will return them back out," start="00:06:03.840" video="mainVideo" id=subtitle]]
[[!template text="or it'll just return the latest." start="00:06:05.520" video="mainVideo" id=subtitle]]
[[!template text="And there's a simple example" start="00:06:07.280" video="mainVideo" id=subtitle]]
[[!template text="that shows it logging," start="00:06:08.479" video="mainVideo" id=subtitle]]
[[!template text="and then shows it coming back out," start="00:06:09.600" video="mainVideo" id=subtitle]]
[[!template text="pretty much what you would expect." start="00:06:11.280" video="mainVideo" id=subtitle]]
[[!template text="Here's another class that adapts" start="00:06:14.080" video="mainVideo" id=subtitle]]
[[!template text="the `emms-player` to the `logger` class." start="00:06:16.400" video="mainVideo" id=subtitle]]
[[!template text="It only extends the logger" start="00:06:19.039" video="mainVideo" id=subtitle]]
[[!template text="because it doesn't need any features" start="00:06:20.560" video="mainVideo" id=subtitle]]
[[!template text="of the `emms-player` class itself." start="00:06:22.400" video="mainVideo" id=subtitle]]
[[!template text="It just implements methods that dispatch" start="00:06:25.039" video="mainVideo" id=subtitle]]
[[!template text="based on it being that logging player class," start="00:06:27.440" video="mainVideo" id=subtitle]]
[[!template text="and you can see it logs whenever" start="00:06:30.240" video="mainVideo" id=subtitle]]
[[!template text="a track is started or stopped," start="00:06:31.759" video="mainVideo" id=subtitle]]
[[!template text="and it also adds some track" start="00:06:34.240" video="mainVideo" id=subtitle]]
[[!template text="to tell you whether or not" start="00:06:36.240" video="mainVideo" id=subtitle]]
[[!template text="the track was playable," start="00:06:37.520" video="mainVideo" id=subtitle]]
[[!template text="that is using the around method." start="00:06:38.560" video="mainVideo" id=subtitle]]
[[!template text="So, you can see we have all three methods" start="00:06:41.199" video="mainVideo" id=subtitle]]
[[!template text="before, after, and around in this class," start="00:06:43.199" video="mainVideo" id=subtitle]]
[[!template text="so you can see how those work." start="00:06:45.280" video="mainVideo" id=subtitle]]
[[!template text="Then you need one more," start="00:06:48.160" video="mainVideo" id=subtitle]]
[[!template text="which is the class" start="00:06:49.440" video="mainVideo" id=subtitle]]
[[!template text="that mixes it all together," start="00:06:50.184" video="mainVideo" id=subtitle]]
[[!template text="So, that's the `logging-player-mpv`," start="00:06:51.759" video="mainVideo" id=subtitle]]
[[!template text="and it extends both the `logging-player` class" start="00:06:54.080" video="mainVideo" id=subtitle]]
[[!template text="and the `emms-player-mpv` class." start="00:06:56.639" video="mainVideo" id=subtitle]]
[[!template text="What's really interesting about this is" start="00:06:59.680" video="mainVideo" id=subtitle]]
[[!template text="that even though the logging player is" start="00:07:01.440" video="mainVideo" id=subtitle]]
[[!template text="part of the `emms-player` hierarchy," start="00:07:03.360" video="mainVideo" id=subtitle]]
[[!template text="it doesn't depend on" start="00:07:05.520" video="mainVideo" id=subtitle]]
[[!template text="a specific implementation," start="00:07:06.472" video="mainVideo" id=subtitle]]
[[!template text="so you can combine the two different" start="00:07:08.240" video="mainVideo" id=subtitle]]
[[!template text="classes that lets the logging class" start="00:07:10.400" video="mainVideo" id=subtitle]]
[[!template text="only care about logging," start="00:07:12.639" video="mainVideo" id=subtitle]]
[[!template text="and the `emms-player` class" start="00:07:13.919" video="mainVideo" id=subtitle]]
[[!template text="only care about playing," start="00:07:15.440" video="mainVideo" id=subtitle]]
[[!template text="and that is a really nice" start="00:07:17.039" video="mainVideo" id=subtitle]]
[[!template text="way of separating your concerns" start="00:07:18.240" video="mainVideo" id=subtitle]]
[[!template text="that I think is very powerful." start="00:07:19.599" video="mainVideo" id=subtitle]]
[[!template text="Here's a quick example of" start="00:07:21.440" video="mainVideo" id=subtitle]]
[[!template text="just how that works," start="00:07:22.515" video="mainVideo" id=subtitle]]
[[!template text="and you can see the `unplayable`" start="00:07:23.599" video="mainVideo" id=subtitle]]
[[!template text="track is not playable," start="00:07:25.199" video="mainVideo" id=subtitle]]
[[!template text="and it gets logged as such," start="00:07:26.160" video="mainVideo" id=subtitle]]
[[!template text="`foo` is playable, and you can see" start="00:07:27.840" video="mainVideo" id=subtitle]]
[[!template text="the logs in started and stopped." start="00:07:29.360" video="mainVideo" id=subtitle]]
[[!template text="So, you can see it's having" start="00:07:31.120" video="mainVideo" id=subtitle]]
[[!template text="the side effects from those methods," start="00:07:32.560" video="mainVideo" id=subtitle]]
[[!template text="and it's also returning" start="00:07:34.000" video="mainVideo" id=subtitle]]
[[!template text="the value off the player as well." start="00:07:36.960" video="mainVideo" id=subtitle]]
[[!template text="I think this system has a bunch of" start="00:07:40.319" video="mainVideo" id=subtitle]]
[[!template text="really nice properties." start="00:07:41.599" video="mainVideo" id=subtitle]]
[[!template text="First and foremost," start="00:07:43.120" video="mainVideo" id=subtitle]]
[[!template text="it feels like a normal Lisp," start="00:07:44.080" video="mainVideo" id=subtitle]]
[[!template text="all you're doing is calling functions," start="00:07:45.840" video="mainVideo" id=subtitle]]
[[!template text="there's no magic involved." start="00:07:47.360" video="mainVideo" id=subtitle]]
[[!template text="Also, you can use either or both of the" start="00:07:49.840" video="mainVideo" id=subtitle]]
[[!template text="classes or generic functions." start="00:07:51.919" video="mainVideo" id=subtitle]]
[[!template text="If you only need to" start="00:07:53.840" video="mainVideo" id=subtitle]]
[[!template text="encapsulate data into a structure," start="00:07:55.120" video="mainVideo" id=subtitle]]
[[!template text="then you can only use classes," start="00:07:56.960" video="mainVideo" id=subtitle]]
[[!template text="you don't have to use generic functions." start="00:07:58.479" video="mainVideo" id=subtitle]]
[[!template text="And if you only need dynamic dispatch," start="00:08:00.400" video="mainVideo" id=subtitle]]
[[!template text="you can only implement" start="00:08:02.080" video="mainVideo" id=subtitle]]
[[!template text="a generic function and methods." start="00:08:03.068" video="mainVideo" id=subtitle]]
[[!template text="You don't get forced into a model" start="00:08:04.720" video="mainVideo" id=subtitle]]
[[!template text="where you have to use both." start="00:08:06.560" video="mainVideo" id=subtitle]]
[[!template text="You can mix and match for" start="00:08:08.000" video="mainVideo" id=subtitle]]
[[!template text="whatever needs your program has," start="00:08:09.247" video="mainVideo" id=subtitle]]
[[!template text="which I think is really amazing." start="00:08:10.800" video="mainVideo" id=subtitle]]
[[!template text="Any value can conform to an interface," start="00:08:13.039" video="mainVideo" id=subtitle]]
[[!template text="meaning a generic function." start="00:08:15.440" video="mainVideo" id=subtitle]]
[[!template text="So, you don't have to use those classes." start="00:08:17.039" video="mainVideo" id=subtitle]]
[[!template text="You can even implement" start="00:08:19.520" video="mainVideo" id=subtitle]]
[[!template text="a generic function over `nil`," start="00:08:20.479" video="mainVideo" id=subtitle]]
[[!template text="which gives you those really nice" start="00:08:22.240" video="mainVideo" id=subtitle]]
[[!template text="properties of Lisp," start="00:08:23.599" video="mainVideo" id=subtitle]]
[[!template text="where you have nil-punning, you know," start="00:08:24.800" video="mainVideo" id=subtitle]]
[[!template text="if you take the head of a nil list," start="00:08:26.460" video="mainVideo" id=subtitle]]
[[!template text="then the output is `nil`," start="00:08:28.800" video="mainVideo" id=subtitle]]
[[!template text="but you can do that" start="00:08:30.479" video="mainVideo" id=subtitle]]
[[!template text="with your object system too." start="00:08:31.283" video="mainVideo" id=subtitle]]
[[!template text="And a really nice feature of that is" start="00:08:32.880" video="mainVideo" id=subtitle]]
[[!template text="that you have no possibility of" start="00:08:34.320" video="mainVideo" id=subtitle]]
[[!template text="null pointer exceptions" start="00:08:35.919" video="mainVideo" id=subtitle]]
[[!template text="like you do in other languages." start="00:08:36.959" video="mainVideo" id=subtitle]]
[[!template text="They have a calling convention" start="00:08:38.719" video="mainVideo" id=subtitle]]
[[!template text="where you call object dot method," start="00:08:39.919" video="mainVideo" id=subtitle]]
[[!template text="but in CLOS, you call a generic function," start="00:08:42.880" video="mainVideo" id=subtitle]]
[[!template text="and you just give it some arguments." start="00:08:45.600" video="mainVideo" id=subtitle]]
[[!template text="Typically, the first one is going to be" start="00:08:47.279" video="mainVideo" id=subtitle]]
[[!template text="an EIEIO class object," start="00:08:48.959" video="mainVideo" id=subtitle]]
[[!template text="but it doesn't have to be," start="00:08:51.680" video="mainVideo" id=subtitle]]
[[!template text="but because you're not calling that" start="00:08:53.200" video="mainVideo" id=subtitle]]
[[!template text="instance of an object," start="00:08:54.640" video="mainVideo" id=subtitle]]
[[!template text="there's nothing to be nil in the first place," start="00:08:55.519" video="mainVideo" id=subtitle]]
[[!template text="so there's no possibility of" start="00:08:57.279" video="mainVideo" id=subtitle]]
[[!template text="a nil pointer exception." start="00:08:58.320" video="mainVideo" id=subtitle]]
[[!template text="And then the ability to" start="00:09:00.080" video="mainVideo" id=subtitle]]
[[!template text="have multiple inheritance" start="00:09:01.376" video="mainVideo" id=subtitle]]
[[!template text="and mix in all of these different" start="00:09:02.480" video="mainVideo" id=subtitle]]
[[!template text="functionalities into your final object" start="00:09:04.000" video="mainVideo" id=subtitle]]
[[!template text="is very powerful." start="00:09:05.760" video="mainVideo" id=subtitle]]
[[!template text="Because you have multiple inheritance," start="00:09:07.279" video="mainVideo" id=subtitle]]
[[!template text="your final object that" start="00:09:09.839" video="mainVideo" id=subtitle]]
[[!template text="composes all of those things" start="00:09:11.120" video="mainVideo" id=subtitle]]
[[!template text="is both a player and a logger," start="00:09:12.560" video="mainVideo" id=subtitle]]
[[!template text="and it can be substituted into code" start="00:09:14.080" video="mainVideo" id=subtitle]]
[[!template text="that expects either of them." start="00:09:15.600" video="mainVideo" id=subtitle]]
[[!template text="It's not an adapter class" start="00:09:17.279" video="mainVideo" id=subtitle]]
[[!template text="that only allows you to do one thing," start="00:09:19.040" video="mainVideo" id=subtitle]]
[[!template text="it does both of them." start="00:09:21.360" video="mainVideo" id=subtitle]]
[[!template text="I think that's amazing." start="00:09:22.560" video="mainVideo" id=subtitle]]
[[!template text="So, here are some practical examples" start="00:09:24.800" video="mainVideo" id=subtitle]]
[[!template text="where I think maybe this" start="00:09:26.320" video="mainVideo" id=subtitle]]
[[!template text="could be a good idea." start="00:09:27.387" video="mainVideo" id=subtitle]]
[[!template text="And I like to think about," start="00:09:28.720" video="mainVideo" id=subtitle]]
[[!template text="&quot;What is OOP actually good for?&quot;." start="00:09:30.399" video="mainVideo" id=subtitle]]
[[!template text="I think it has three really amazing powers," start="00:09:32.320" video="mainVideo" id=subtitle]]
[[!template text="encapsulation, abstraction," start="00:09:34.640" video="mainVideo" id=subtitle]]
[[!template text="and extensibility," start="00:09:36.399" video="mainVideo" id=subtitle]]
[[!template text="so let's look at those." start="00:09:37.279" video="mainVideo" id=subtitle]]
[[!template text="Encapsulation is just keeping" start="00:09:39.200" video="mainVideo" id=subtitle]]
[[!template text="related data together." start="00:09:40.959" video="mainVideo" id=subtitle]]
[[!template text="Here's an example from the" start="00:09:42.480" video="mainVideo" id=subtitle]]
[[!template text="transmission Torrent client." start="00:09:43.680" video="mainVideo" id=subtitle]]
[[!template text="In order for it to work," start="00:09:45.360" video="mainVideo" id=subtitle]]
[[!template text="it needs to have all four of" start="00:09:46.399" video="mainVideo" id=subtitle]]
[[!template text="these variables set consistently," start="00:09:47.600" video="mainVideo" id=subtitle]]
[[!template text="but if you use the customization interface," start="00:09:49.920" video="mainVideo" id=subtitle]]
[[!template text="they're kind of strewn all over the buffer" start="00:09:52.240" video="mainVideo" id=subtitle]]
[[!template text="because that shows them alphabetically" start="00:09:53.920" video="mainVideo" id=subtitle]]
[[!template text="by variable name instead of" start="00:09:55.760" video="mainVideo" id=subtitle]]
[[!template text="grouping them logically by function." start="00:09:57.040" video="mainVideo" id=subtitle]]
[[!template text="You also have all these" start="00:09:59.920" video="mainVideo" id=subtitle]]
[[!template text="in the global namespace," start="00:10:01.327" video="mainVideo" id=subtitle]]
[[!template text="so you need this disambiguation in front," start="00:10:02.480" video="mainVideo" id=subtitle]]
[[!template text="you have to have a transmission prefix," start="00:10:04.720" video="mainVideo" id=subtitle]]
[[!template text="so it's kind of ugly." start="00:10:06.800" video="mainVideo" id=subtitle]]
[[!template text="An alternative example would be to" start="00:10:08.720" video="mainVideo" id=subtitle]]
[[!template text="encapsulate all of that" start="00:10:10.240" video="mainVideo" id=subtitle]]
[[!template text="in a single class." start="00:10:11.760" video="mainVideo" id=subtitle]]
[[!template text="This has one slot for each of those values," start="00:10:13.360" video="mainVideo" id=subtitle]]
[[!template text="except the username" start="00:10:16.160" video="mainVideo" id=subtitle]]
[[!template text="and password is broken out," start="00:10:17.040" video="mainVideo" id=subtitle]]
[[!template text="there was only one in the previous example," start="00:10:18.000" video="mainVideo" id=subtitle]]
[[!template text="but it works pretty much the same." start="00:10:20.240" video="mainVideo" id=subtitle]]
[[!template text="The really neat thing about this is that" start="00:10:23.120" video="mainVideo" id=subtitle]]
[[!template text="the customization interface understands" start="00:10:25.200" video="mainVideo" id=subtitle]]
[[!template text="how to customize EIEIO objects," start="00:10:27.279" video="mainVideo" id=subtitle]]
[[!template text="so you can set your custom variable" start="00:10:29.920" video="mainVideo" id=subtitle]]
[[!template text="to the value of an object," start="00:10:32.640" video="mainVideo" id=subtitle]]
[[!template text="and in the customization interface," start="00:10:34.000" video="mainVideo" id=subtitle]]
[[!template text="it shows you all of the fields," start="00:10:35.760" video="mainVideo" id=subtitle]]
[[!template text="and it lets you edit the values" start="00:10:37.040" video="mainVideo" id=subtitle]]
[[!template text="of those slots directly." start="00:10:38.399" video="mainVideo" id=subtitle]]
[[!template text="So, that keeps that logical grouping" start="00:10:40.079" video="mainVideo" id=subtitle]]
[[!template text="that I think makes things really easy to use." start="00:10:41.760" video="mainVideo" id=subtitle]]
[[!template text="Another thing it's really good at is" start="00:10:44.800" video="mainVideo" id=subtitle]]
[[!template text="abstraction, and this is really core to" start="00:10:46.160" video="mainVideo" id=subtitle]]
[[!template text="a lot of what Emacs does" start="00:10:48.268" video="mainVideo" id=subtitle]]
[[!template text="because it runs on so many different systems," start="00:10:49.408" video="mainVideo" id=subtitle]]
[[!template text="and it works with so many different" start="00:10:51.200" video="mainVideo" id=subtitle]]
[[!template text="kinds of similar tools." start="00:10:53.308" video="mainVideo" id=subtitle]]
[[!template text="Here's an example from" start="00:10:55.120" video="mainVideo" id=subtitle]]
[[!template text="the built-in SQL implementation." start="00:10:56.109" video="mainVideo" id=subtitle]]
[[!template text="This is the definition of" start="00:10:58.079" video="mainVideo" id=subtitle]]
[[!template text="the postgres backend," start="00:10:59.360" video="mainVideo" id=subtitle]]
[[!template text="there's one of these for" start="00:11:01.040" video="mainVideo" id=subtitle]]
[[!template text="every supported database backend." start="00:11:02.160" video="mainVideo" id=subtitle]]
[[!template text="And you can see, this is a pretty" start="00:11:04.000" video="mainVideo" id=subtitle]]
[[!template text="classic interface abstraction pattern." start="00:11:05.440" video="mainVideo" id=subtitle]]
[[!template text="On the left-hand side," start="00:11:08.480" video="mainVideo" id=subtitle]]
[[!template text="you have a symbol that's common" start="00:11:09.680" video="mainVideo" id=subtitle]]
[[!template text="among all the database backends," start="00:11:10.880" video="mainVideo" id=subtitle]]
[[!template text="and the code that doesn't" start="00:11:12.399" video="mainVideo" id=subtitle]]
[[!template text="know about the implementation can use," start="00:11:14.160" video="mainVideo" id=subtitle]]
[[!template text="no matter what implementation" start="00:11:16.240" video="mainVideo" id=subtitle]]
[[!template text="is being specified." start="00:11:17.519" video="mainVideo" id=subtitle]]
[[!template text="On the right-hand side," start="00:11:19.040" video="mainVideo" id=subtitle]]
[[!template text="you have the implementation" start="00:11:20.000" video="mainVideo" id=subtitle]]
[[!template text="specific values," start="00:11:21.120" video="mainVideo" id=subtitle]]
[[!template text="in some cases these are just strings," start="00:11:22.560" video="mainVideo" id=subtitle]]
[[!template text="or regexes, and in others" start="00:11:24.399" video="mainVideo" id=subtitle]]
[[!template text="those are actual functions." start="00:11:25.760" video="mainVideo" id=subtitle]]
[[!template text="So, really this already is" start="00:11:27.519" video="mainVideo" id=subtitle]]
[[!template text="object orientation," start="00:11:29.440" video="mainVideo" id=subtitle]]
[[!template text="it's just an ad-hoc system for it," start="00:11:30.720" video="mainVideo" id=subtitle]]
[[!template text="but you don't have to use an ad-hoc system" start="00:11:32.959" video="mainVideo" id=subtitle]]
[[!template text="because there's this" start="00:11:34.880" video="mainVideo" id=subtitle]]
[[!template text="nice formal one instead." start="00:11:35.519" video="mainVideo" id=subtitle]]
[[!template text="Another thing that it's" start="00:11:38.000" video="mainVideo" id=subtitle]]
[[!template text="really good at is extensibility," start="00:11:38.880" video="mainVideo" id=subtitle]]
[[!template text="we saw some of that with" start="00:11:40.959" video="mainVideo" id=subtitle]]
[[!template text="the emms-player example earlier." start="00:11:42.160" video="mainVideo" id=subtitle]]
[[!template text="But here's another thing I think" start="00:11:44.800" video="mainVideo" id=subtitle]]
[[!template text="it would be interesting to explore." start="00:11:46.160" video="mainVideo" id=subtitle]]
[[!template text="Emacs has this idea of derived modes" start="00:11:48.720" video="mainVideo" id=subtitle]]
[[!template text="where you have a mode that's based on" start="00:11:51.279" video="mainVideo" id=subtitle]]
[[!template text="another, and that's a pretty clear" start="00:11:52.639" video="mainVideo" id=subtitle]]
[[!template text="inheritance pattern straight out of OOP" start="00:11:54.639" video="mainVideo" id=subtitle]]
[[!template text="as far as I'm concerned." start="00:11:57.040" video="mainVideo" id=subtitle]]
[[!template text="What would it look like" start="00:11:58.560" video="mainVideo" id=subtitle]]
[[!template text="if major modes were EIEIO classes," start="00:12:00.079" video="mainVideo" id=subtitle]]
[[!template text="and you could extend your mode" start="00:12:02.959" video="mainVideo" id=subtitle]]
[[!template text="by extending the class." start="00:12:04.800" video="mainVideo" id=subtitle]]
[[!template text="I think that's a really interesting idea," start="00:12:06.399" video="mainVideo" id=subtitle]]
[[!template text="and I'd like to explore that more." start="00:12:08.240" video="mainVideo" id=subtitle]]
[[!template text="In conclusion, I think EIEIO is amazing," start="00:12:10.880" video="mainVideo" id=subtitle]]
[[!template text="and I had no idea that such a powerful" start="00:12:14.079" video="mainVideo" id=subtitle]]
[[!template text="object orientation system" start="00:12:16.079" video="mainVideo" id=subtitle]]
[[!template text="was available in the Emacs." start="00:12:18.079" video="mainVideo" id=subtitle]]
[[!template text="My goal with this talk" start="00:12:20.160" video="mainVideo" id=subtitle]]
[[!template text="is for anyone who writes Emacs Lisp," start="00:12:21.519" video="mainVideo" id=subtitle]]
[[!template text="to look at these classes of problems," start="00:12:23.519" video="mainVideo" id=subtitle]]
[[!template text="encapsulation, abstraction," start="00:12:25.360" video="mainVideo" id=subtitle]]
[[!template text="and extensibility," start="00:12:27.360" video="mainVideo" id=subtitle]]
[[!template text="and if you run into" start="00:12:28.639" video="mainVideo" id=subtitle]]
[[!template text="those problems in your code," start="00:12:29.600" video="mainVideo" id=subtitle]]
[[!template text="instead of immediately reaching" start="00:12:31.279" video="mainVideo" id=subtitle]]
[[!template text="and building your own system," start="00:12:33.279" video="mainVideo" id=subtitle]]
[[!template text="I want you to think:" start="00:12:34.959" video="mainVideo" id=subtitle]]
[[!template text="&quot;Oh there's a thing for that," start="00:12:35.760" video="mainVideo" id=subtitle]]
[[!template text="and I can just use it.&quot;" start="00:12:37.279" video="mainVideo" id=subtitle]]
[[!template text="That's my talk, thanks." start="00:12:39.040" video="mainVideo" id=subtitle]]
[[!template text="Hack on!" start="00:12:40.560" video="mainVideo" id=subtitle]]
[[!template text="captions by bhavin192 (Bhavin Gandhi)" start="00:12:41.560" video="mainVideo" id=subtitle]]