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