From 72e48bc52524672fc6179d1f45f091df76cd2e02 Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Sun, 13 Dec 2020 00:08:14 -0500 Subject: Switch to vtt --- ...he-gnus-newsreader--eric-abrahamsen-autogen.sbv | 2214 -------------------- 1 file changed, 2214 deletions(-) delete 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 deleted file mode 100644 index 814b5e8a..00000000 --- a/2020/subtitles/emacsconf-2020--32-object-oriented-code-in-the-gnus-newsreader--eric-abrahamsen-autogen.sbv +++ /dev/null @@ -1,2214 +0,0 @@ -0:00:01.839,0:00:05.759 -hello EmacsConf - -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