From 839b298776e262a99eec18d23f4e52363fe937bc Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Wed, 9 Dec 2020 12:17:50 -0500 Subject: Add more autogenerated subtitles --- ...he-gnus-newsreader--eric-abrahamsen-autogen.sbv | 2214 ++++++++++++++++++++ 1 file changed, 2214 insertions(+) create mode 100644 2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv (limited to '2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv') diff --git a/2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv b/2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv new file mode 100644 index 00000000..43b07fa8 --- /dev/null +++ b/2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv @@ -0,0 +1,2214 @@ +0:00:01.839,0:00:05.759 +hello emacs conf + +0:00:04.160,0:00:07.200 +thanks very much first of all to the + +0:00:05.759,0:00:09.440 +organizers of the conference + +0:00:07.200,0:00:10.480 +and to the audience who i hope is out + +0:00:09.440,0:00:12.080 +there somewhere + +0:00:10.480,0:00:14.240 +uh for giving me this chance to talk + +0:00:12.080,0:00:16.560 +about emacs and some of my uh + +0:00:14.240,0:00:18.480 +my poking around with emacs lisp my name + +0:00:16.560,0:00:20.960 +is eric abrahamson i'm not + +0:00:18.480,0:00:21.920 +a professional programmer but i use + +0:00:20.960,0:00:24.800 +emacs all day + +0:00:21.920,0:00:26.160 +every day for writing for translating + +0:00:24.800,0:00:28.160 +for project management + +0:00:26.160,0:00:29.199 +and most importantly for email which + +0:00:28.160,0:00:32.480 +will be the + +0:00:29.199,0:00:35.440 +subject of my talk today so i'm talking + +0:00:32.480,0:00:38.320 +about object-oriented code in emacs + +0:00:35.440,0:00:40.160 +uh most famous possibly oldest + +0:00:38.320,0:00:41.760 +definitely most notorious news reader + +0:00:40.160,0:00:44.320 +slash emacs client + +0:00:41.760,0:00:45.440 +email client so in particular object + +0:00:44.320,0:00:49.520 +oriented code + +0:00:45.440,0:00:49.520 +in news why object-oriented code + +0:00:50.239,0:00:53.600 +the way news works is it started off as + +0:00:51.920,0:00:57.039 +a news reader so for access + +0:00:53.600,0:00:59.120 +accessing nntp servers and later on grew + +0:00:57.039,0:01:01.039 +a whole bunch of new functionality as a + +0:00:59.120,0:01:02.079 +mail client so it can talk to imap + +0:01:01.039,0:01:04.799 +servers + +0:01:02.079,0:01:06.640 +mail dealer directories uh folders on + +0:01:04.799,0:01:08.400 +your file system all kinds of stuff + +0:01:06.640,0:01:09.760 +but it presents a unified interface to + +0:01:08.400,0:01:11.040 +all those things so it's basically + +0:01:09.760,0:01:14.000 +polymorphism + +0:01:11.040,0:01:16.400 +one of the the basic fundamental + +0:01:14.000,0:01:18.720 +principles of object oriented code so + +0:01:16.400,0:01:19.920 +it's a good fit second reason is it + +0:01:18.720,0:01:22.880 +already is + +0:01:19.920,0:01:23.759 +object oriented and i'll get into what + +0:01:22.880,0:01:27.280 +that means + +0:01:23.759,0:01:28.640 +in a second so + +0:01:27.280,0:01:30.640 +the background that you should know is + +0:01:28.640,0:01:32.560 +that most of this code was written in + +0:01:30.640,0:01:34.880 +the 90s + +0:01:32.560,0:01:36.159 +emacs lisp has only grown sort of + +0:01:34.880,0:01:38.640 +official + +0:01:36.159,0:01:41.200 +object orientation support libraries + +0:01:38.640,0:01:43.840 +over the past 10 years or so + +0:01:41.200,0:01:44.799 +from about 2010 to the present so what + +0:01:43.840,0:01:48.640 +does + +0:01:44.799,0:01:50.560 +news do so the basics of + +0:01:48.640,0:01:52.240 +object orientation in most languages are + +0:01:50.560,0:01:53.759 +you you define + +0:01:52.240,0:01:55.840 +a class of some sort and then you + +0:01:53.759,0:01:58.079 +instantiate that class and these + +0:01:55.840,0:02:00.320 +class instances have two things they + +0:01:58.079,0:02:01.759 +have data attributes or + +0:02:00.320,0:02:04.799 +slots or members or whatever you're + +0:02:01.759,0:02:07.280 +going to call them and they have + +0:02:04.799,0:02:08.399 +methods which operate on individual + +0:02:07.280,0:02:11.120 +instances + +0:02:08.399,0:02:12.879 +so you could say that you create or + +0:02:11.120,0:02:13.920 +instantiate an instance of a class in + +0:02:12.879,0:02:16.239 +that instance + +0:02:13.920,0:02:17.120 +owns two things that owns its set of + +0:02:16.239,0:02:20.239 +attributes + +0:02:17.120,0:02:23.280 +and it owns some methods which + +0:02:20.239,0:02:26.720 +also work on the on the instance + +0:02:23.280,0:02:29.040 +so both in nurse's existing code and in + +0:02:26.720,0:02:30.080 +the more standard object oriented emacs + +0:02:29.040,0:02:32.480 +lisp libraries + +0:02:30.080,0:02:34.080 +this relationship is turned on its head + +0:02:32.480,0:02:37.599 +a little bit + +0:02:34.080,0:02:40.239 +in that data slots and + +0:02:37.599,0:02:41.360 +uh and instance methods are defined + +0:02:40.239,0:02:42.959 +outside of the + +0:02:41.360,0:02:45.040 +class or the instances themselves so + +0:02:42.959,0:02:46.879 +they are top level definitions + +0:02:45.040,0:02:48.319 +so we'll get to what that means in the + +0:02:46.879,0:02:49.840 +in the newer libraries um + +0:02:48.319,0:02:51.760 +in a bit but uh first i want to talk + +0:02:49.840,0:02:54.319 +about how news does this and in order to + +0:02:51.760,0:02:57.440 +do that we are going to go deep into + +0:02:54.319,0:02:59.879 +the darkest corner of the new co source + +0:02:57.440,0:03:02.879 +code tree to a library called + +0:02:59.879,0:03:05.040 +nno.l very cryptically + +0:03:02.879,0:03:06.800 +titled uh library and when we open it up + +0:03:05.040,0:03:09.519 +we find + +0:03:06.800,0:03:11.040 +a library with no code comments and + +0:03:09.519,0:03:12.800 +almost no doc strings + +0:03:11.040,0:03:14.159 +almost as if lars was a little ashamed + +0:03:12.800,0:03:16.000 +not ashamed but knew he was doing + +0:03:14.159,0:03:19.040 +something a little bit crazy + +0:03:16.000,0:03:21.040 +and didn't want anyone to see so + +0:03:19.040,0:03:22.400 +this file contains the the object + +0:03:21.040,0:03:24.480 +oriented mechanism + +0:03:22.400,0:03:25.760 +whereby you can define different kinds + +0:03:24.480,0:03:27.280 +of back ends for news + +0:03:25.760,0:03:29.760 +and then those back ends can be + +0:03:27.280,0:03:32.480 +instantiated as individual + +0:03:29.760,0:03:33.360 +servers and as you define these backends + +0:03:32.480,0:03:36.000 +you're supposed to use + +0:03:33.360,0:03:36.640 +two macros which you can see here one is + +0:03:36.000,0:03:39.599 +called def + +0:03:36.640,0:03:41.280 +vu and one is called defu and if you + +0:03:39.599,0:03:43.280 +look at the definitions the definitions + +0:03:41.280,0:03:45.440 +look pretty simple here def vu basically + +0:03:43.280,0:03:49.040 +turns into a def var + +0:03:45.440,0:03:52.239 +and foo turns into a defund + +0:03:49.040,0:03:55.760 +and along with those basic definitions + +0:03:52.239,0:03:58.720 +the library also does some registration + +0:03:55.760,0:04:00.080 +memoization caching of those variables + +0:03:58.720,0:04:01.840 +it saves them in the structure + +0:04:00.080,0:04:03.360 +for later use so that we know that those + +0:04:01.840,0:04:05.280 +are meant to be + +0:04:03.360,0:04:06.640 +uh attributes and methods that are used + +0:04:05.280,0:04:08.000 +with instances + +0:04:06.640,0:04:09.280 +with server instances but you can see + +0:04:08.000,0:04:10.560 +that there's no server instance + +0:04:09.280,0:04:13.200 +definition here there's no + +0:04:10.560,0:04:14.239 +like no nothing these are top level + +0:04:13.200,0:04:18.160 +these are top level + +0:04:14.239,0:04:18.639 +definitions so really data attributes + +0:04:18.160,0:04:22.000 +for + +0:04:18.639,0:04:23.840 +new servers and + +0:04:22.000,0:04:25.440 +methods or functions that operate on + +0:04:23.840,0:04:28.400 +those instances are completely + +0:04:25.440,0:04:29.600 +separate mechanisms they don't really + +0:04:28.400,0:04:31.680 +have anything to do with each other they + +0:04:29.600,0:04:36.560 +don't belong to the same data structures + +0:04:31.680,0:04:36.560 +so how do they work follow me + +0:04:37.120,0:04:41.360 +aka methods and attributes these are all + +0:04:39.520,0:04:44.479 +the things i just said + +0:04:41.360,0:04:47.360 +so when you define a + +0:04:44.479,0:04:47.360 +a backend type + +0:04:48.560,0:04:52.400 +in noose what you get is this a + +0:04:51.199,0:04:54.080 +definition a list + +0:04:52.400,0:04:55.520 +and it'll say there is such a back end + +0:04:54.080,0:04:58.880 +as nnml + +0:04:55.520,0:04:59.520 +and these are its uh data attributes + +0:04:58.880,0:05:01.840 +that any + +0:04:59.520,0:05:02.960 +given instance can have and then these + +0:05:01.840,0:05:04.960 +are + +0:05:02.960,0:05:06.880 +the functions or methods that are + +0:05:04.960,0:05:08.960 +defined to operate on + +0:05:06.880,0:05:11.440 +an instance of this backend so a server + +0:05:08.960,0:05:13.360 +that belongs to the nnml + +0:05:11.440,0:05:15.120 +backend so at least we have this data + +0:05:13.360,0:05:16.880 +here so that's that's handy we don't you + +0:05:15.120,0:05:18.000 +don't really touch that that's like very + +0:05:16.880,0:05:20.560 +very very deep + +0:05:18.000,0:05:22.560 +um use code that doesn't really come up + +0:05:20.560,0:05:25.280 +even as a + +0:05:22.560,0:05:26.479 +even as a bug squasher or whatever we + +0:05:25.280,0:05:27.280 +don't touch that very often but there + +0:05:26.479,0:05:30.400 +they are and that's + +0:05:27.280,0:05:32.080 +that's how they work now the next thing + +0:05:30.400,0:05:34.000 +that obviously you want to know is okay + +0:05:32.080,0:05:35.039 +where are if i've started up news where + +0:05:34.000,0:05:37.199 +are my servers + +0:05:35.039,0:05:39.199 +uh where are these server objects since + +0:05:37.199,0:05:41.840 +this is object oriented + +0:05:39.199,0:05:43.199 +programming and the weird thing that you + +0:05:41.840,0:05:45.199 +will eventually + +0:05:43.199,0:05:46.880 +figure out in some cases after years of + +0:05:45.199,0:05:49.199 +poking around in the new source code + +0:05:46.880,0:05:50.320 +is that servers do not exist in an + +0:05:49.199,0:05:53.440 +ontological + +0:05:50.320,0:05:55.440 +philosophical sense as objects the + +0:05:53.440,0:05:57.039 +primary data structures of noose are + +0:05:55.440,0:05:58.960 +groups + +0:05:57.039,0:06:00.720 +and in sort of an object-oriented + +0:05:58.960,0:06:01.759 +hierarchical you know mindset you'd + +0:06:00.720,0:06:03.759 +think well + +0:06:01.759,0:06:05.759 +groups belong to servers so servers must + +0:06:03.759,0:06:08.000 +exist but they don't + +0:06:05.759,0:06:09.360 +each group and here you can see some + +0:06:08.000,0:06:11.199 +examples of groups + +0:06:09.360,0:06:13.039 +these are basically the data structures + +0:06:11.199,0:06:14.960 +that represent a group each group also + +0:06:13.039,0:06:17.039 +has a little entry here that + +0:06:14.960,0:06:18.000 +that tells you what server it belongs to + +0:06:17.039,0:06:20.479 +and each group + +0:06:18.000,0:06:23.120 +replicates that data uh saying which + +0:06:20.479,0:06:24.479 +server it belongs to and so when + +0:06:23.120,0:06:26.160 +nurse is going through doing its + +0:06:24.479,0:06:27.680 +business uh trying to figure out what's + +0:06:26.160,0:06:29.840 +like updating mail from the groups or + +0:06:27.680,0:06:31.600 +whatever almost every time + +0:06:29.840,0:06:32.960 +it will cycle through all the list of + +0:06:31.600,0:06:34.960 +groups it'll + +0:06:32.960,0:06:36.720 +it'll look at all the server definitions + +0:06:34.960,0:06:38.160 +and it will categorize the groups by + +0:06:36.720,0:06:41.120 +server + +0:06:38.160,0:06:42.160 +which which is just weird because you're + +0:06:41.120,0:06:43.840 +sort of looking for okay where does the + +0:06:42.160,0:06:44.479 +server exist it doesn't exist it's put + +0:06:43.840,0:06:48.319 +together + +0:06:44.479,0:06:50.400 +every time uh out of out of code + +0:06:48.319,0:06:51.840 +elsewhere in the news code base + +0:06:50.400,0:06:54.080 +specifically from these group + +0:06:51.840,0:06:55.199 +these group definitions and so this is + +0:06:54.080,0:06:58.080 +very odd because + +0:06:55.199,0:06:58.720 +in in some sense like here this one its + +0:06:58.080,0:07:02.240 +server is + +0:06:58.720,0:07:03.919 +nnml and an empty string so there's a + +0:07:02.240,0:07:04.479 +certain sense here in which this server + +0:07:03.919,0:07:06.400 +is not + +0:07:04.479,0:07:07.759 +really an object at all what it is is a + +0:07:06.400,0:07:08.560 +set of instructions for how to find + +0:07:07.759,0:07:11.199 +messages + +0:07:08.560,0:07:12.800 +and this set of instructions is go to + +0:07:11.199,0:07:15.440 +the default place where the user + +0:07:12.800,0:07:16.000 +might have their mail and expect to find + +0:07:15.440,0:07:18.080 +messages + +0:07:16.000,0:07:19.840 +there in an nml format which is + +0:07:18.080,0:07:22.479 +basically just one message per + +0:07:19.840,0:07:23.840 +um per file and any number of groups + +0:07:22.479,0:07:25.440 +could have those same instructions uh + +0:07:23.840,0:07:26.720 +but they're not it's not really a thing + +0:07:25.440,0:07:28.639 +it's really just a + +0:07:26.720,0:07:30.240 +it's more of a procedural instruction + +0:07:28.639,0:07:31.919 +and on the other end of the spectrum you + +0:07:30.240,0:07:33.599 +might have an nni map + +0:07:31.919,0:07:35.840 +server which very much is a thing it has + +0:07:33.599,0:07:37.759 +its own it has its own server its own + +0:07:35.840,0:07:40.240 +port its own authentication + +0:07:37.759,0:07:41.360 +system so some of the servers are more + +0:07:40.240,0:07:42.400 +like things some of the servers are more + +0:07:41.360,0:07:45.520 +like instructions + +0:07:42.400,0:07:47.280 +as news works right now um these + +0:07:45.520,0:07:48.879 +most of the servers are treated like + +0:07:47.280,0:07:50.879 +just instruction sets + +0:07:48.879,0:07:53.120 +and and there's no place where you can + +0:07:50.879,0:07:55.360 +go and find them there's no one central + +0:07:53.120,0:07:56.160 +uh variable that defines them all so how + +0:07:55.360,0:07:57.520 +do the + +0:07:56.160,0:07:59.520 +um so we'll talk about the methods in a + +0:07:57.520,0:08:02.639 +second how do the data attributes work + +0:07:59.520,0:08:04.479 +uh put very crudely um + +0:08:02.639,0:08:05.919 +your servers when they're put together + +0:08:04.479,0:08:08.080 +uh they are okay they are + +0:08:05.919,0:08:08.960 +kept in a variable and it's called nno + +0:08:08.080,0:08:11.120 +nno + +0:08:08.960,0:08:12.960 +state a list and there's a concept to + +0:08:11.120,0:08:16.560 +this of the current server + +0:08:12.960,0:08:19.039 +so when we go here let's go back to + +0:08:16.560,0:08:20.560 +our nnno definition a list so when we + +0:08:19.039,0:08:22.240 +have an nnml + +0:08:20.560,0:08:24.400 +server say we have one here and it's + +0:08:22.240,0:08:26.639 +just this blank string + +0:08:24.400,0:08:28.879 +these are all when you define that in + +0:08:26.639,0:08:31.919 +your own uh server definition code + +0:08:28.879,0:08:32.399 +you can put in different values for all + +0:08:31.919,0:08:35.760 +of these + +0:08:32.399,0:08:37.039 +various attributes and when noose comes + +0:08:35.760,0:08:38.959 +when it comes time for news to operate + +0:08:37.039,0:08:40.640 +on this server in particular ask it to + +0:08:38.959,0:08:42.080 +you know open a group or get new mail + +0:08:40.640,0:08:45.360 +what it will do is it will take + +0:08:42.080,0:08:45.920 +that particular server's data from these + +0:08:45.360,0:08:47.600 +symbols + +0:08:45.920,0:08:49.600 +and it will copy all that information + +0:08:47.600,0:08:51.760 +into the global devfars + +0:08:49.600,0:08:53.120 +so for the time that you are operating + +0:08:51.760,0:08:55.920 +on this particular server + +0:08:53.120,0:08:56.800 +its individual data becomes the values + +0:08:55.920,0:08:59.360 +of these global + +0:08:56.800,0:09:00.560 +variables which when you realize what's + +0:08:59.360,0:09:02.080 +happening is sort of terrifying you + +0:09:00.560,0:09:04.480 +think oh my god + +0:09:02.080,0:09:05.760 +but at the same time it's actually kind + +0:09:04.480,0:09:07.279 +of impressive and it's amazing that it + +0:09:05.760,0:09:09.120 +works as well as it does + +0:09:07.279,0:09:10.880 +i'm actually a little bit in awe of the + +0:09:09.120,0:09:12.560 +of the code in this in this library i + +0:09:10.880,0:09:15.760 +think it's pretty impressive + +0:09:12.560,0:09:18.320 +so as you nno change server + +0:09:15.760,0:09:20.080 +uh this function here these values get + +0:09:18.320,0:09:21.440 +copied into the global value into the + +0:09:20.080,0:09:22.399 +global variables and then as you go on + +0:09:21.440,0:09:24.000 +the next server + +0:09:22.399,0:09:26.399 +that gets you know cleaned out and + +0:09:24.000,0:09:29.680 +recopied there are a few + +0:09:26.399,0:09:32.000 +um a few other slot types + +0:09:29.680,0:09:33.440 +or attribute types which do because all + +0:09:32.000,0:09:34.720 +of these attributes see they all start + +0:09:33.440,0:09:37.920 +with the nml + +0:09:34.720,0:09:40.560 +or in this case and in folder prefix + +0:09:37.920,0:09:41.760 +but there are a few slot types that all + +0:09:40.560,0:09:43.279 +servers need for + +0:09:41.760,0:09:45.920 +for instance their most recent status + +0:09:43.279,0:09:46.640 +message a status symbol like open denied + +0:09:45.920,0:09:48.080 +whatever + +0:09:46.640,0:09:49.680 +and that data is sort of scattered + +0:09:48.080,0:09:51.200 +around the rest of the news + +0:09:49.680,0:09:53.440 +code base in various variables or + +0:09:51.200,0:09:55.440 +various places + +0:09:53.440,0:09:56.560 +so that's that sort of just contributes + +0:09:55.440,0:09:57.360 +to the confusion when you're trying to + +0:09:56.560,0:10:00.720 +figure out why + +0:09:57.360,0:10:03.839 +things are going wrong so that is our + +0:10:00.720,0:10:05.440 +um nnoo which is and + +0:10:03.839,0:10:07.360 +sort of how the attributes and these + +0:10:05.440,0:10:09.120 +global variables work + +0:10:07.360,0:10:10.480 +if we want to talk about defu and the + +0:10:09.120,0:10:19.839 +methods we + +0:10:10.480,0:10:19.839 +go to + +0:10:20.800,0:10:25.600 +and so this is the place where all the + +0:10:23.200,0:10:27.200 +server level methods are defined + +0:10:25.600,0:10:29.279 +and what we have here are things like + +0:10:27.200,0:10:32.640 +here's an example there's closed server + +0:10:29.279,0:10:36.320 +this closed server is given a + +0:10:32.640,0:10:38.079 +a server as a an argument + +0:10:36.320,0:10:40.560 +it looks at the server and basically it + +0:10:38.079,0:10:42.079 +finds the proper function to call on + +0:10:40.560,0:10:45.120 +this particular server + +0:10:42.079,0:10:45.600 +using the function new skip function by + +0:10:45.120,0:10:48.959 +taking + +0:10:45.600,0:10:49.760 +the sort of latter half of this function + +0:10:48.959,0:10:52.079 +symbol + +0:10:49.760,0:10:53.440 +and pasting it together with the symbol + +0:10:52.079,0:10:56.800 +that represents the back end so + +0:10:53.440,0:10:59.600 +if you were calling this on an nni map + +0:10:56.800,0:11:01.279 +server your skip function would look at + +0:10:59.600,0:11:02.240 +your imap server look at closed server i + +0:11:01.279,0:11:05.120 +knew what + +0:11:02.240,0:11:05.120 +it would come up with + +0:11:07.839,0:11:11.920 +server sure enough there's an imac close + +0:11:10.240,0:11:12.240 +server and it'll call this code and then + +0:11:11.920,0:11:14.000 +it'll + +0:11:12.240,0:11:15.279 +it'll go and do its other bookkeeping + +0:11:14.000,0:11:18.320 +another sort of + +0:11:15.279,0:11:19.279 +surrounding code and so that's not that + +0:11:18.320,0:11:22.640 +actually works pretty well + +0:11:19.279,0:11:24.959 +uh as as things go uh defu + +0:11:22.640,0:11:26.800 +makes a record that this this function + +0:11:24.959,0:11:28.320 +exists and nus gets function get + +0:11:26.800,0:11:29.600 +function looks on that cache finds the + +0:11:28.320,0:11:30.959 +function and calls it + +0:11:29.600,0:11:32.560 +now what's particularly confusing is + +0:11:30.959,0:11:33.360 +that you don't actually even have to use + +0:11:32.560,0:11:35.519 +defu + +0:11:33.360,0:11:38.399 +so whoever wrote and then mail gear + +0:11:35.519,0:11:39.920 +which is a weird library + +0:11:38.399,0:11:41.600 +said to heck with you i'm not using any + +0:11:39.920,0:11:43.120 +of these + +0:11:41.600,0:11:45.839 +any of this machinery i'm going to do it + +0:11:43.120,0:11:49.680 +myself so we have + +0:11:45.839,0:11:52.320 +def structs to hold uh the instance + +0:11:49.680,0:11:53.040 +data and then we have just plain old + +0:11:52.320,0:11:55.680 +defense + +0:11:53.040,0:11:57.279 +for things like animal your close server + +0:11:55.680,0:11:59.279 +request close all of these + +0:11:57.279,0:12:00.320 +these server level uh variables and it + +0:11:59.279,0:12:03.360 +just turns out that + +0:12:00.320,0:12:05.839 +news in its belt and suspenders + +0:12:03.360,0:12:07.279 +approach to uh to coding it'll actually + +0:12:05.839,0:12:10.320 +just go out if it can't find + +0:12:07.279,0:12:12.160 +the memoized function it'll just go out + +0:12:10.320,0:12:14.240 +and say has anybody defined a function + +0:12:12.160,0:12:16.000 +that looks like this pattern and then + +0:12:14.240,0:12:17.920 +and then melder says yes i did and then + +0:12:16.000,0:12:19.920 +we call it and then we go so it's just + +0:12:17.920,0:12:21.440 +it's fine it works it just adds to the + +0:12:19.920,0:12:24.240 +confusion why + +0:12:21.440,0:12:25.440 +why does it work we don't know sometimes + +0:12:24.240,0:12:26.880 +the only thing worse than not knowing + +0:12:25.440,0:12:30.000 +why something doesn't work is + +0:12:26.880,0:12:30.560 +not knowing why something does work um + +0:12:30.000,0:12:31.920 +and then + +0:12:30.560,0:12:33.680 +a last little bit i want to touch on + +0:12:31.920,0:12:35.440 +here is inheritance which is another + +0:12:33.680,0:12:38.480 +sort of cornerstone of object-oriented + +0:12:35.440,0:12:40.160 +coding as far as i can tell only uh + +0:12:38.480,0:12:41.920 +the only inheritance that goes on is in + +0:12:40.160,0:12:45.519 +something called nn male + +0:12:41.920,0:12:48.399 +which provides sort of common functions + +0:12:45.519,0:12:49.360 +for back ends that keep their mail on + +0:12:48.399,0:12:52.000 +your + +0:12:49.360,0:12:53.680 +local machine and you can spool it you + +0:12:52.000,0:12:55.440 +can delete it you can you know you own + +0:12:53.680,0:12:56.160 +the messages it's not like an nntp + +0:12:55.440,0:12:59.040 +server + +0:12:56.160,0:13:00.160 +and so a lot of those male deer nnml + +0:12:59.040,0:13:02.959 +whatever + +0:13:00.160,0:13:04.079 +a lot of those have sort of similar code + +0:13:02.959,0:13:07.600 +which they + +0:13:04.079,0:13:09.600 +which they share via this nn mail + +0:13:07.600,0:13:12.959 +you call it an abstract parent class i + +0:13:09.600,0:13:15.440 +guess so if you have something like nnml + +0:13:12.959,0:13:16.720 +it has a request scan uh when it goes + +0:13:15.440,0:13:18.800 +into request scan + +0:13:16.720,0:13:21.760 +it ends up calling nnmail.newmail and it + +0:13:18.800,0:13:23.279 +says i am calling this as an nml server + +0:13:21.760,0:13:24.959 +and here are some of my callback + +0:13:23.279,0:13:26.000 +functions and my variables that i would + +0:13:24.959,0:13:28.000 +like you to use + +0:13:26.000,0:13:30.120 +when you are getting your email so in + +0:13:28.000,0:13:33.120 +this way the code is sort of you know + +0:13:30.120,0:13:35.680 +inter-interleaved between the the child + +0:13:33.120,0:13:37.120 +class and the parent class even though + +0:13:35.680,0:13:39.440 +we're not talking in terms of classes + +0:13:37.120,0:13:42.160 +here at all really + +0:13:39.440,0:13:42.959 +so that's how noose works right now i + +0:13:42.160,0:13:45.519 +hope that's clear + +0:13:42.959,0:13:46.560 +it certainly wasn't to me and i still + +0:13:45.519,0:13:48.079 +have to go refresh my + +0:13:46.560,0:13:50.079 +memory i'd like to talk a little bit + +0:13:48.079,0:13:51.600 +about sort of the newer + +0:13:50.079,0:13:54.240 +libraries that are available now for + +0:13:51.600,0:13:56.959 +doing object-oriented code + +0:13:54.240,0:13:59.279 +uh as i mentioned i think earlier nno + +0:13:56.959,0:14:00.320 +the copyright headers for 1996 so that's + +0:13:59.279,0:14:02.639 +pretty venerable + +0:14:00.320,0:14:05.519 +coincidentally around the same time eric + +0:14:02.639,0:14:08.320 +ludlum started developing e-i-e-i-o + +0:14:05.519,0:14:09.360 +which is a which is sort of inspired by + +0:14:08.320,0:14:12.720 +a common lisp's + +0:14:09.360,0:14:14.240 +common lisp object system um i got a + +0:14:12.720,0:14:14.959 +very good introduction to that from this + +0:14:14.240,0:14:16.399 +book + +0:14:14.959,0:14:18.000 +practical common lisp which i would + +0:14:16.399,0:14:20.079 +encourage you to look at if you haven't + +0:14:18.000,0:14:22.320 +which you probably have anyway + +0:14:20.079,0:14:23.920 +e-i-e-i-o was incorporated into emacs in + +0:14:22.320,0:14:27.839 +2010 + +0:14:23.920,0:14:30.240 +so that yeah e-i-e-i-o provides um + +0:14:27.839,0:14:32.079 +the deaf class statements it provides + +0:14:30.240,0:14:32.639 +deaf generics deaf methods all that sort + +0:14:32.079,0:14:34.800 +of stuff + +0:14:32.639,0:14:36.320 +sort of a common lisp object-oriented + +0:14:34.800,0:14:38.399 +code + +0:14:36.320,0:14:39.760 +at some point stephan monier's money + +0:14:38.399,0:14:41.199 +money another name i haven't pronounced + +0:14:39.760,0:14:43.839 +it all out + +0:14:41.199,0:14:45.120 +started either cleaning up that code or + +0:14:43.839,0:14:46.959 +for one reason or another writing a + +0:14:45.120,0:14:48.000 +re-implementation of generic functions + +0:14:46.959,0:14:51.440 +which was added + +0:14:48.000,0:14:51.920 +uh in 2015 and then throughout this time + +0:14:51.440,0:14:54.639 +another + +0:14:51.920,0:14:55.760 +sort of object-oriented style + +0:14:54.639,0:14:58.160 +declaration is + +0:14:55.760,0:15:00.000 +defstruct which started off in the cl + +0:14:58.160,0:15:01.600 +libraries + +0:15:00.000,0:15:02.959 +implemented with vectors later was + +0:15:01.600,0:15:04.639 +implemented with records so they're + +0:15:02.959,0:15:06.720 +easier to target + +0:15:04.639,0:15:08.399 +anyway that's another option so how + +0:15:06.720,0:15:09.279 +would we this is i'm probably out of + +0:15:08.399,0:15:13.040 +time already but + +0:15:09.279,0:15:13.040 +we're only getting to the part + +0:15:13.839,0:15:17.920 +the whole point of this is how would we + +0:15:15.760,0:15:19.920 +rewrite someone news's code to use these + +0:15:17.920,0:15:21.760 +newer libraries + +0:15:19.920,0:15:23.839 +if we didn't have to support third party + +0:15:21.760,0:15:26.639 +libraries this wouldn't be that hard + +0:15:23.839,0:15:28.160 +but out there noose is really up on uh + +0:15:26.639,0:15:30.240 +you know backwards compatibility and not + +0:15:28.160,0:15:33.040 +breaking people's stuff and you know + +0:15:30.240,0:15:34.240 +multi-decade support for things so there + +0:15:33.040,0:15:35.759 +are people out there who have written + +0:15:34.240,0:15:38.480 +third-party libraries + +0:15:35.759,0:15:40.000 +um defining new backends for you can use + +0:15:38.480,0:15:41.759 +like hacker news or whatever as + +0:15:40.000,0:15:43.199 +a as a server so we want to be able to + +0:15:41.759,0:15:44.240 +support those if you didn't have to + +0:15:43.199,0:15:46.079 +support those it'd be fine you'd + +0:15:44.240,0:15:47.440 +re-implement you'd use generic functions + +0:15:46.079,0:15:48.560 +you'd use either structure classes + +0:15:47.440,0:15:51.040 +whatever but we got a + +0:15:48.560,0:15:52.000 +it's a little bit tricky to support + +0:15:51.040,0:15:54.320 +these other people's + +0:15:52.000,0:15:56.079 +libraries so one of the things we can do + +0:15:54.320,0:15:59.279 +is rewrite the defu + +0:15:56.079,0:16:00.079 +so if you remember defu is the thing + +0:15:59.279,0:16:03.120 +that uh + +0:16:00.079,0:16:04.800 +or sorry uh defu + +0:16:03.120,0:16:07.040 +is the thing that defines methods that + +0:16:04.800,0:16:10.160 +operate on object answers + +0:16:07.040,0:16:10.639 +instances and we can uh rewrite that to + +0:16:10.160,0:16:13.440 +use + +0:16:10.639,0:16:14.240 +cldef generic and that's this is fairly + +0:16:13.440,0:16:15.440 +fairly simple + +0:16:14.240,0:16:17.759 +it looks like a lot of code it's not a + +0:16:15.440,0:16:20.320 +lot of good for instance we have the + +0:16:17.759,0:16:21.199 +new closed server code that we looked at + +0:16:20.320,0:16:22.720 +earlier + +0:16:21.199,0:16:24.560 +and we have this phone call and the new + +0:16:22.720,0:16:28.720 +skip function so this would look + +0:16:24.560,0:16:30.240 +like using generic functions and methods + +0:16:28.720,0:16:32.959 +it would look like this we'd have + +0:16:30.240,0:16:34.560 +a generic def generic which is just a + +0:16:32.959,0:16:36.320 +sort of a declaration + +0:16:34.560,0:16:37.680 +and a doc string and then we have those + +0:16:36.320,0:16:40.320 +implementations + +0:16:37.680,0:16:42.399 +so we can see what the original code + +0:16:40.320,0:16:44.720 +does here is it first says okay what + +0:16:42.399,0:16:45.839 +type is our our is our argument here and + +0:16:44.720,0:16:48.560 +if it's a string + +0:16:45.839,0:16:50.160 +then go and get the proper s the proper + +0:16:48.560,0:16:52.480 +method definition + +0:16:50.160,0:16:53.920 +from that string so the way we do that + +0:16:52.480,0:16:56.000 +with methods is we + +0:16:53.920,0:16:57.440 +we say if the server is a string so if + +0:16:56.000,0:16:58.720 +it matches this type + +0:16:57.440,0:17:00.320 +then what we're going to do is just + +0:16:58.720,0:17:02.160 +recall we're going to call this function + +0:17:00.320,0:17:05.199 +all over again + +0:17:02.160,0:17:06.400 +using uh basically the same code here + +0:17:05.199,0:17:07.600 +the same code that takes a string and + +0:17:06.400,0:17:10.640 +gets the object so + +0:17:07.600,0:17:11.600 +this does this can add extra function + +0:17:10.640,0:17:12.880 +calls + +0:17:11.600,0:17:14.880 +depending on how you've written the rest + +0:17:12.880,0:17:16.640 +of your code um but this is sort of the + +0:17:14.880,0:17:19.679 +canonical way of doing this + +0:17:16.640,0:17:20.559 +uh using methods then our next part here + +0:17:19.679,0:17:22.000 +is + +0:17:20.559,0:17:24.559 +nishkit function we're going to get a + +0:17:22.000,0:17:26.079 +function called closed server + +0:17:24.559,0:17:27.360 +the difference here is that all these + +0:17:26.079,0:17:28.000 +functions are all going to be called + +0:17:27.360,0:17:29.360 +close + +0:17:28.000,0:17:31.120 +news close server they're not going to + +0:17:29.360,0:17:32.799 +be called news like nni my + +0:17:31.120,0:17:34.400 +closed server and ntp close server + +0:17:32.799,0:17:36.160 +they're all going to have the same name + +0:17:34.400,0:17:37.440 +and what we do is uh we have an around + +0:17:36.160,0:17:40.640 +method + +0:17:37.440,0:17:43.679 +for any server that is a const which is + +0:17:40.640,0:17:45.520 +which is as close as we care to get uh + +0:17:43.679,0:17:46.799 +for you know zeroing in on the type that + +0:17:45.520,0:17:48.559 +we're looking for + +0:17:46.799,0:17:50.480 +we put in a round method on that so that + +0:17:48.559,0:17:51.679 +we can call the next method which we'll + +0:17:50.480,0:17:53.440 +call the more specific + +0:17:51.679,0:17:55.600 +method and then we have our other + +0:17:53.440,0:17:57.280 +bookkeeping code to clean up you know + +0:17:55.600,0:17:58.640 +set up tear down code we'll go around + +0:17:57.280,0:18:00.080 +that + +0:17:58.640,0:18:02.080 +and then in one of the back-end + +0:18:00.080,0:18:04.320 +definitions for instance in an imap + +0:18:02.080,0:18:05.760 +we have another news closed server thing + +0:18:04.320,0:18:08.880 +this looks at the server + +0:18:05.760,0:18:10.799 +and it says is this server a list that + +0:18:08.880,0:18:12.480 +starts with a symbol and an imap and if + +0:18:10.799,0:18:13.679 +it is then we're almost guaranteed that + +0:18:12.480,0:18:15.840 +this is what we wanted + +0:18:13.679,0:18:17.600 +and then this is where we would insert + +0:18:15.840,0:18:18.960 +all the rest of the code from anonymous + +0:18:17.600,0:18:20.799 +closed server + +0:18:18.960,0:18:22.880 +where we'd re-redefine that to look like + +0:18:20.799,0:18:26.080 +this so it's not that hard + +0:18:22.880,0:18:28.720 +theoretically so what we would do + +0:18:26.080,0:18:29.679 +is take the defu macro macro and then + +0:18:28.720,0:18:32.240 +rewrite that + +0:18:29.679,0:18:33.039 +so that it actually defines a cl def + +0:18:32.240,0:18:35.520 +method like + +0:18:33.039,0:18:36.320 +one of these now there's a couple of + +0:18:35.520,0:18:38.960 +these things + +0:18:36.320,0:18:41.200 +unfortunately it's not that easy get rid + +0:18:38.960,0:18:43.490 +of you + +0:18:41.200,0:18:46.400 +a couple of these things + +0:18:43.490,0:18:49.039 +[Music] + +0:18:46.400,0:18:49.919 +that don't use their server as the first + +0:18:49.039,0:18:52.400 +argument + +0:18:49.919,0:18:53.280 +or any of the arguments or it's an + +0:18:52.400,0:18:54.720 +optional argument + +0:18:53.280,0:18:56.640 +and we need the server to be in there to + +0:18:54.720,0:18:58.799 +dispatch on its type + +0:18:56.640,0:19:00.080 +if the server doesn't show up as a as a + +0:18:58.799,0:19:01.760 +required + +0:19:00.080,0:19:03.600 +argument we're not going to be able to + +0:19:01.760,0:19:07.440 +locate the the proper + +0:19:03.600,0:19:10.640 +function call so in the case of + +0:19:07.440,0:19:12.080 +noose request group here we start with + +0:19:10.640,0:19:12.720 +the group it's the group that matters + +0:19:12.080,0:19:14.960 +and we get + +0:19:12.720,0:19:16.240 +the newscommand method as an optional + +0:19:14.960,0:19:18.559 +argument + +0:19:16.240,0:19:20.480 +so that's not cool we don't want that so + +0:19:18.559,0:19:21.360 +what we need instead is something that + +0:19:20.480,0:19:23.840 +looks like this + +0:19:21.360,0:19:25.360 +what we're going to do with uh this is + +0:19:23.840,0:19:26.640 +gonna be just terrible terrible code but + +0:19:25.360,0:19:28.160 +hopefully it won't get used very often + +0:19:26.640,0:19:30.559 +it's gonna be really embarrassing + +0:19:28.160,0:19:31.520 +um defu what's what definitely was gonna + +0:19:30.559,0:19:33.200 +have to do is + +0:19:31.520,0:19:34.559 +say okay is this a function that doesn't + +0:19:33.200,0:19:35.360 +have the server as the first argument + +0:19:34.559,0:19:36.960 +and if it does + +0:19:35.360,0:19:38.400 +it's gonna say oh it's news request + +0:19:36.960,0:19:39.280 +group what happens has to happen with + +0:19:38.400,0:19:40.799 +news request group + +0:19:39.280,0:19:43.200 +is we take the news command method and + +0:19:40.799,0:19:46.240 +we're going to move it up to the front + +0:19:43.200,0:19:47.520 +to the first argument here and it's + +0:19:46.240,0:19:48.720 +either going to be + +0:19:47.520,0:19:50.840 +it's either going to be given or it's + +0:19:48.720,0:19:52.080 +going to be nil because it's it is + +0:19:50.840,0:19:54.320 +optional + +0:19:52.080,0:19:55.760 +okay i briefly edited the space time + +0:19:54.320,0:19:56.400 +continuum there to conceal the fact that + +0:19:55.760,0:19:57.679 +i had + +0:19:56.400,0:19:59.440 +actually not finished writing the code + +0:19:57.679,0:20:02.159 +that i was supposed to write anyway + +0:19:59.440,0:20:02.960 +um so now we have once we've reordered + +0:20:02.159,0:20:04.320 +the + +0:20:02.960,0:20:05.760 +the arguments to the function then we + +0:20:04.320,0:20:06.880 +have to check our various possible + +0:20:05.760,0:20:08.640 +values one is + +0:20:06.880,0:20:10.080 +uh that the server was not passed in in + +0:20:08.640,0:20:12.400 +which case we recall + +0:20:10.080,0:20:13.840 +request group with the server um the + +0:20:12.400,0:20:15.360 +other is that it's just a string in + +0:20:13.840,0:20:16.559 +which case we do that and then this is + +0:20:15.360,0:20:18.559 +sort of the the normal + +0:20:16.559,0:20:20.720 +the normal case that we would expect to + +0:20:18.559,0:20:21.039 +cons so that's not that bad it's not you + +0:20:20.720,0:20:23.760 +know + +0:20:21.039,0:20:24.480 +it's not beautiful um i would be sort of + +0:20:23.760,0:20:26.159 +ashamed to + +0:20:24.480,0:20:28.000 +let anybody see that particular macro + +0:20:26.159,0:20:30.640 +but i think that it would work okay + +0:20:28.000,0:20:31.440 +now the more difficult thing is going to + +0:20:30.640,0:20:34.640 +be + +0:20:31.440,0:20:37.600 +the data variables so + +0:20:34.640,0:20:39.360 +the equivalent of def vu because our two + +0:20:37.600,0:20:41.039 +options for defining classes here are + +0:20:39.360,0:20:41.919 +def struct and def class both of which + +0:20:41.039,0:20:45.280 +required you + +0:20:41.919,0:20:46.960 +to define the slots inside this macro + +0:20:45.280,0:20:49.039 +itself + +0:20:46.960,0:20:51.280 +so defu is top level um how do we get + +0:20:49.039,0:20:55.039 +the top level this top level macro + +0:20:51.280,0:20:56.240 +uh to insert slot names into these + +0:20:55.039,0:20:58.960 +definitions it's + +0:20:56.240,0:21:00.240 +it's possible that it'll be um that i + +0:20:58.960,0:21:03.039 +could monkey patch + +0:21:00.240,0:21:04.799 +uh an existing struct or an existing + +0:21:03.039,0:21:05.280 +class to add a new slot into it that + +0:21:04.799,0:21:07.760 +sounds + +0:21:05.280,0:21:09.600 +ugly the other option would be to give + +0:21:07.760,0:21:11.520 +it a server variable slot which is just + +0:21:09.600,0:21:13.760 +a generalized bucket + +0:21:11.520,0:21:15.520 +that holds anything that gets defined + +0:21:13.760,0:21:16.720 +via def loop + +0:21:15.520,0:21:18.799 +i don't like either of those solutions + +0:21:16.720,0:21:22.480 +but i'm i don't see any other + +0:21:18.799,0:21:25.520 +any other way of doing that so we re + +0:21:22.480,0:21:27.440 +rewrite the nno declare macro to either + +0:21:25.520,0:21:29.840 +be a destructor or a def class + +0:21:27.440,0:21:31.039 +and we rewrite the def boom macro to + +0:21:29.840,0:21:33.039 +somehow + +0:21:31.039,0:21:34.480 +associate that variable name the symbol + +0:21:33.039,0:21:36.159 +with the with the resulting class + +0:21:34.480,0:21:37.760 +definition + +0:21:36.159,0:21:39.600 +then the last question is do we use + +0:21:37.760,0:21:41.600 +structure classes + +0:21:39.600,0:21:43.200 +they both got their their strengths and + +0:21:41.600,0:21:46.480 +their weaknesses + +0:21:43.200,0:21:47.520 +the nice thing is that i mean i've got + +0:21:46.480,0:21:49.600 +how many servers you're going to have + +0:21:47.520,0:21:51.919 +really i've got i think less than 10 + +0:21:49.600,0:21:52.960 +uh truly deranged mine might have as as + +0:21:51.919,0:21:55.440 +many as + +0:21:52.960,0:21:56.480 +50 let's double that to 100 100 of + +0:21:55.440,0:21:58.400 +anything is not going to matter it + +0:21:56.480,0:22:00.159 +doesn't matter what we use + +0:21:58.400,0:22:02.720 +death structures are simpler they're + +0:22:00.159,0:22:05.600 +lighter weight they're defined on top of + +0:22:02.720,0:22:06.960 +the direct the c records so you know + +0:22:05.600,0:22:08.559 +that's nice + +0:22:06.960,0:22:10.320 +the slots don't carry very much + +0:22:08.559,0:22:11.760 +information with them there's no type + +0:22:10.320,0:22:14.480 +information there's no doc string for + +0:22:11.760,0:22:16.559 +the slots themselves + +0:22:14.480,0:22:17.919 +they can also only do single inheritance + +0:22:16.559,0:22:21.120 +which some might say + +0:22:17.919,0:22:22.640 +was an advantage def class each slot + +0:22:21.120,0:22:24.000 +gets a lot more information associated + +0:22:22.640,0:22:24.480 +with it with it which i think can be + +0:22:24.000,0:22:27.120 +nice + +0:22:24.480,0:22:28.799 +it can do multiple inheritance if you're + +0:22:27.120,0:22:30.720 +going to go there + +0:22:28.799,0:22:32.640 +they are heavier weight in particular + +0:22:30.720,0:22:34.080 +their printed representation is gross + +0:22:32.640,0:22:35.840 +it's enormous + +0:22:34.080,0:22:37.520 +so if you see one show up in a back + +0:22:35.840,0:22:38.240 +trace or in your messages buffer can + +0:22:37.520,0:22:39.520 +really + +0:22:38.240,0:22:41.360 +it can really blow that up and make it + +0:22:39.520,0:22:43.200 +hard to read this of course won't be an + +0:22:41.360,0:22:46.240 +issue because our code won't have any + +0:22:43.200,0:22:48.320 +errors in it um my argument for multiple + +0:22:46.240,0:22:51.280 +inheritance here is that i can imagine + +0:22:48.320,0:22:52.720 +new servers falling into sort of like a + +0:22:51.280,0:22:56.240 +little two by two matrix of + +0:22:52.720,0:22:56.799 +of parent classes one being news versus + +0:22:56.240,0:23:00.320 +mail + +0:22:56.799,0:23:00.720 +so news the messages belong to somebody + +0:23:00.320,0:23:02.080 +else + +0:23:00.720,0:23:03.840 +you can't touch them you can't delete + +0:23:02.080,0:23:06.000 +them mail meaning + +0:23:03.840,0:23:08.960 +the messages are under your command + +0:23:06.000,0:23:11.039 +either a local mail dealer a remote imap + +0:23:08.960,0:23:12.640 +you're allowed to spool them copy them + +0:23:11.039,0:23:13.919 +delete them at will + +0:23:12.640,0:23:16.400 +and then the other sort of line of the + +0:23:13.919,0:23:19.760 +matrix would be a local file system + +0:23:16.400,0:23:20.559 +versus some kind of a you know server + +0:23:19.760,0:23:23.280 +port + +0:23:20.559,0:23:24.960 +remote access and that second the server + +0:23:23.280,0:23:26.880 +port remote access thing might require + +0:23:24.960,0:23:28.559 +authentication it might require a keep + +0:23:26.880,0:23:30.159 +alive for a connection + +0:23:28.559,0:23:31.600 +um it's there's going to be a process + +0:23:30.159,0:23:32.400 +there rather than just file system + +0:23:31.600,0:23:33.840 +commands + +0:23:32.400,0:23:35.360 +so i could see if i was going to do + +0:23:33.840,0:23:36.240 +multiple inheritance that's what i would + +0:23:35.360,0:23:39.039 +do those two + +0:23:36.240,0:23:40.400 +those two possible parent classes anyway + +0:23:39.039,0:23:41.520 +that's as far as i've gotten + +0:23:40.400,0:23:43.279 +i thought that i would be able to write + +0:23:41.520,0:23:44.720 +more of this code before i did this talk + +0:23:43.279,0:23:46.720 +but instead i spent the whole time + +0:23:44.720,0:23:48.320 +messing with video codecs but that's + +0:23:46.720,0:23:49.440 +where we're at and i'm going to cut + +0:23:48.320,0:23:50.960 +myself off now + +0:23:49.440,0:23:53.440 +i hope there are questions i hope i'm + +0:23:50.960,0:23:55.919 +there to to answer your questions + +0:23:53.440,0:23:57.120 +and thanks very much again to everyone + +0:23:55.919,0:23:59.279 +involved + +0:23:57.120,0:23:59.279 +bye + -- cgit v1.2.3