summaryrefslogtreecommitdiffstats
path: root/2021/captions/form.md
diff options
context:
space:
mode:
Diffstat (limited to '2021/captions/form.md')
-rw-r--r--2021/captions/form.md430
1 files changed, 430 insertions, 0 deletions
diff --git a/2021/captions/form.md b/2021/captions/form.md
new file mode 100644
index 00000000..76984b28
--- /dev/null
+++ b/2021/captions/form.md
@@ -0,0 +1,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]]