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