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