< Return to Video

Lecture 8: Metaprogramming (2020)

  • 0:01 - 0:05
    all right everyone let's get started
  • 0:03 - 0:08
    with the next lecture so today we're
  • 0:05 - 0:10
    gonna that tackle the topic of meta
  • 0:08 - 0:12
    programming and this title is a little
  • 0:10 - 0:14
    weird it's not entirely clear what we
  • 0:12 - 0:15
    mean by meta programming we couldn't
  • 0:14 - 0:17
    really come up with a better name for
  • 0:15 - 0:21
    this lecture because this lecture is
  • 0:17 - 0:22
    about the processes that surround the
  • 0:21 - 0:25
    work that you do when working with
  • 0:22 - 0:28
    software it is not about programming
  • 0:25 - 0:31
    itself necessarily but about the process
  • 0:28 - 0:34
    this can be things like how your system
  • 0:31 - 0:36
    is built how it's tested how you add
  • 0:34 - 0:37
    dependencies to your software that sort
  • 0:36 - 0:40
    of stuff that becomes really relevant
  • 0:37 - 0:42
    when you build larger pieces of software
  • 0:40 - 0:44
    but they're not really programming in
  • 0:42 - 0:46
    and of themselves
  • 0:44 - 0:49
    so the first thing we're going to talk
  • 0:46 - 0:52
    about in this lecture is the notion of
  • 0:49 - 0:54
    build systems so how many of you have
  • 0:52 - 0:59
    used a build system before or know what
  • 0:54 - 1:02
    it is okay so about 1/2 of you so for
  • 0:59 - 1:05
    the rest of you the the central idea
  • 1:02 - 1:07
    behind a build system is that you're
  • 1:05 - 1:10
    writing a paper you're writing software
  • 1:07 - 1:12
    you're like working on a class whatever
  • 1:10 - 1:14
    it might be and you have a bunch of
  • 1:12 - 1:16
    commands that you like either written
  • 1:14 - 1:18
    down in your shell history or you wrote
  • 1:16 - 1:19
    them down in a document somewhere that
  • 1:18 - 1:21
    you know you have to run if you want to
  • 1:19 - 1:23
    do a particular thing so for example
  • 1:21 - 1:24
    like there are a sequence of commands so
  • 1:23 - 1:27
    you need to run in order to build your
  • 1:24 - 1:29
    paper or build your thesis or just to
  • 1:27 - 1:33
    run the tests for whatever class you're
  • 1:29 - 1:35
    currently in and a build system sort of
  • 1:33 - 1:38
    idea is that you want to encode these
  • 1:35 - 1:40
    rules for what commands to run in order
  • 1:38 - 1:44
    to build particular targets into a tool
  • 1:40 - 1:45
    that can do it for you and in particular
  • 1:44 - 1:47
    you're going to teach this tool about
  • 1:45 - 1:51
    the dependencies between those different
  • 1:47 - 1:54
    artifacts that you might build there are
  • 1:51 - 1:57
    a lot of different types of tools of
  • 1:54 - 1:58
    this kind and many of them are built for
  • 1:57 - 2:00
    particular purposes particularly
  • 1:58 - 2:02
    languages some of them are built for
  • 2:00 - 2:04
    building like papers some of them are
  • 2:02 - 2:06
    built for building software some of them
  • 2:04 - 2:10
    are built for particularly programming
  • 2:06 - 2:13
    languages like Java or some some tools
  • 2:10 - 2:16
    even have built in tools for for builds
  • 2:13 - 2:17
    so NPM for example you might be aware if
  • 2:16 - 2:19
    you've done Nodejs development has a
  • 2:17 - 2:21
    bunch of built-in tools for doing
  • 2:19 - 2:23
    tracking of dependencies and building
  • 2:21 - 2:25
    them and building all of the dependent
  • 2:23 - 2:27
    stuff of your software but more
  • 2:25 - 2:30
    generally these are known as build
  • 2:27 - 2:33
    systems and at their core they all
  • 2:30 - 2:36
    function in a very similar way and that
  • 2:33 - 2:37
    is you have a number of targets these
  • 2:36 - 2:41
    are the things that you want to build
  • 2:37 - 2:42
    these are things like paper dot PDF but
  • 2:41 - 2:45
    they can also be more abstract things
  • 2:42 - 2:47
    like run the test suite or build the
  • 2:45 - 2:49
    binary for this program then you have a
  • 2:47 - 2:51
    bunch of dependencies and dependencies
  • 2:49 - 2:53
    are things that need to be built in
  • 2:51 - 2:56
    order for this thing to be built and
  • 2:53 - 2:58
    then you have rules that define how do
  • 2:56 - 3:01
    you go from a complete list of
  • 2:58 - 3:03
    dependencies to the given target so an
  • 3:01 - 3:05
    example of this might be in order to
  • 3:03 - 3:09
    build my paper dot PDF I need a bunch of
  • 3:05 - 3:11
    like plot images they're gonna go into
  • 3:09 - 3:13
    the paper so they need to be built but
  • 3:11 - 3:15
    then once they have been built how do i
  • 3:13 - 3:17
    construct the paper given those files so
  • 3:15 - 3:18
    that is what a rule is it's a sequence
  • 3:17 - 3:21
    of command so you run to get from one to
  • 3:18 - 3:24
    the other how you encode these rules
  • 3:21 - 3:26
    differs between different tools in this
  • 3:24 - 3:29
    particular class we're gonna focus on a
  • 3:26 - 3:31
    tool called make make is a tool that you
  • 3:29 - 3:33
    will find on almost any system that you
  • 3:31 - 3:36
    log in today like it'll be on Mac OS
  • 3:33 - 3:38
    it'll be on basically every Linux and
  • 3:36 - 3:41
    BSD system and you can pretty easily get
  • 3:38 - 3:43
    it on Windows um it's not great for very
  • 3:41 - 3:45
    complex software but it works really
  • 3:43 - 3:50
    well for anything that's sort of simple
  • 3:45 - 3:52
    to medium complexity now when you run
  • 3:50 - 3:53
    make to make user command you can run on
  • 3:52 - 3:56
    the command line and when you type make
  • 3:53 - 3:59
    and this is an empty directory if I type
  • 3:56 - 4:02
    make it just has no target specified and
  • 3:59 - 4:04
    no make file found stop and so it
  • 4:02 - 4:06
    helpfully tells you that it stopped
  • 4:04 - 4:09
    running but also tells you that no make
  • 4:06 - 4:11
    file was found make will look for a file
  • 4:09 - 4:13
    literally called make file in the
  • 4:11 - 4:15
    current directory and that is where you
  • 4:13 - 4:18
    encode these targets dependencies and
  • 4:15 - 4:20
    rules so let's try to write one let's
  • 4:18 - 4:22
    imagine that I'm writing this
  • 4:20 - 4:24
    hypothetical paper and so I'm gonna make
  • 4:22 - 4:26
    a make file and then this make file I'm
  • 4:24 - 4:28
    going to say that my paper dog PDF the
  • 4:26 - 4:31
    hands-on that's what the : here
  • 4:28 - 4:36
    indicates paper dot text was going to be
  • 4:31 - 4:40
    a little attack file and plot data dot
  • 4:36 - 4:43
    PNG and the command in order to build
  • 4:40 - 4:46
    this is going to be PDF latex of paper
  • 4:43 - 4:48
    dot Tex so for those of you who are not
  • 4:46 - 4:50
    familiar with this particular way of
  • 4:48 - 4:53
    building documents the tech is a really
  • 4:50 - 4:56
    handy programming language for documents
  • 4:53 - 4:58
    it's a really ugly language and it's a
  • 4:56 - 5:01
    pain to work with but it produces pretty
  • 4:58 - 5:05
    nice documents and the tool you use to
  • 5:01 - 5:09
    go from a tech file to PDF is PDF latex
  • 5:05 - 5:12
    and here I'm saying that I also depend
  • 5:09 - 5:14
    on this plot plot data PNG that's gonna
  • 5:12 - 5:17
    be included in my document and what I'm
  • 5:14 - 5:19
    really saying here is if either of those
  • 5:17 - 5:22
    two dependencies change I want you to
  • 5:19 - 5:24
    build paper PDF they both need to be
  • 5:22 - 5:26
    present and should they ever change I
  • 5:24 - 5:28
    wanted to rebuild it but I haven't
  • 5:26 - 5:31
    really told it how to generate this plot
  • 5:28 - 5:32
    data PNG so I might want to rule for
  • 5:31 - 5:34
    that as well
  • 5:32 - 5:36
    so I'm gonna define another target here
  • 5:34 - 5:42
    and it's gonna be it's gonna look like
  • 5:36 - 5:45
    this plot - % & % means and make is any
  • 5:42 - 5:47
    string sort of a wildcard pattern but
  • 5:45 - 5:50
    the cool thing is a you go and repeat
  • 5:47 - 5:53
    this pattern in the dependencies so I
  • 5:50 - 5:59
    can say that plot - % dot PNG is going
  • 5:53 - 6:02
    to depend on % dott data or debt that is
  • 5:59 - 6:05
    a common sort of suffix for data files
  • 6:02 - 6:07
    and it's also going to depend on some
  • 6:05 - 6:09
    script that's gonna actually plot this
  • 6:07 - 6:10
    for me and the rules for to go from one
  • 6:09 - 6:11
    to the other
  • 6:10 - 6:13
    these can be multiple lines but in my
  • 6:11 - 6:16
    particular case they're just one line
  • 6:13 - 6:21
    I'm gonna explain what this is in a
  • 6:16 - 6:24
    little second alright so here we're
  • 6:21 - 6:26
    gonna say that in order to go from a
  • 6:24 - 6:29
    wildcard dot dot file that matches the
  • 6:26 - 6:33
    wildcard in the target and a plot dot
  • 6:29 - 6:34
    python file run the python file with - i
  • 6:33 - 6:36
    which is going to be like the way we
  • 6:34 - 6:38
    take the mark what the input is in our
  • 6:36 - 6:40
    python file I'll show it to you later
  • 6:38 - 6:42
    dollarz star
  • 6:40 - 6:45
    is a special variable that is defined
  • 6:42 - 6:48
    for you and make file rules that matches
  • 6:45 - 6:51
    whatever the percentile was so if I do
  • 6:48 - 6:53
    plot to PNG then it's going to look for
  • 6:51 - 6:56
    food dot that and it dollars stars can
  • 6:53 - 6:57
    expand to foo so this will produce the
  • 6:56 - 7:00
    same file name as the one we matched
  • 6:57 - 7:01
    here and dollar act as a special
  • 7:00 - 7:05
    variable that means the name of the
  • 7:01 - 7:07
    target right so the output file and
  • 7:05 - 7:09
    hopefully what plotter py will do is
  • 7:07 - 7:12
    that it will take whatever the data is
  • 7:09 - 7:14
    here it will produce a PNG somehow and
  • 7:12 - 7:18
    it will write it into the file indicated
  • 7:14 - 7:20
    by the dollar at all right so now we
  • 7:18 - 7:21
    have a make file let's see what happens
  • 7:20 - 7:23
    if the only file in this directory is
  • 7:21 - 7:26
    the make file and we run make one says
  • 7:23 - 7:30
    no rule to make target paper dot tex
  • 7:26 - 7:33
    needed by paper dot PDF stop so what
  • 7:30 - 7:35
    it's saying here is first of all it
  • 7:33 - 7:38
    looked at the first rule of our file the
  • 7:35 - 7:39
    first target and when you give make no
  • 7:38 - 7:41
    arguments it tries to build whatever the
  • 7:39 - 7:43
    first target is this is known as the
  • 7:41 - 7:46
    default goal so in this case it tried to
  • 7:43 - 7:48
    helpfully build paper dot PDF for us and
  • 7:46 - 7:50
    then it looked up the dependencies and
  • 7:48 - 7:53
    it said well in order to build paper dot
  • 7:50 - 7:56
    PDF I need paper Tex and I need this PNG
  • 7:53 - 7:59
    file and I can't find paper dot X and I
  • 7:56 - 8:01
    don't have a rule for generating paper
  • 7:59 - 8:04
    dot X and therefore I'm gonna exit this
  • 8:01 - 8:04
    isn't nothing more I can do
  • 8:05 - 8:10
    so let's try to make some files here
  • 8:07 - 8:14
    let's just make like an empty paper dot
  • 8:10 - 8:16
    X and then type make so now it says no
  • 8:14 - 8:18
    rule to make target plot data dot PNG
  • 8:16 - 8:20
    needed by paper to PDF right so now it's
  • 8:18 - 8:21
    it knows that it has one dependency but
  • 8:20 - 8:24
    it doesn't know how to get the other one
  • 8:21 - 8:26
    it knows it as a target that matches but
  • 8:24 - 8:29
    it can't actually find its dependencies
  • 8:26 - 8:32
    and so it ends up doing nothing at all
  • 8:29 - 8:36
    it still still needs us to generate this
  • 8:32 - 8:38
    PNG for the input for the PNG so let's
  • 8:36 - 8:43
    actually put some useful stuff into
  • 8:38 - 8:48
    these files let's say that luckily I
  • 8:43 - 8:50
    have one from earlier plot da py to here
  • 8:48 - 8:52
    so let's so good well this text file is
  • 8:50 - 8:53
    this is what text looks like it's not
  • 8:52 - 8:55
    very pretty but
  • 8:53 - 8:57
    see I'm defining an empty document I'm
  • 8:55 - 9:00
    going to include graphics which is the
  • 8:57 - 9:02
    way you include a an image file I'm
  • 9:00 - 9:04
    going to include plot data dot PNG and
  • 9:02 - 9:06
    this is of course why we want a
  • 9:04 - 9:10
    dependency of peda paper dot PDF to be
  • 9:06 - 9:13
    the PNG file plot the py is also not
  • 9:10 - 9:15
    very interesting it just part imports a
  • 9:13 - 9:19
    bunch libraries it parses the - ion - Oh
  • 9:15 - 9:23
    arguments it loads data from the I
  • 9:19 - 9:25
    argument it uses library called
  • 9:23 - 9:28
    matplotlib which is very handy for just
  • 9:25 - 9:30
    quickly plotting data and it's gonna
  • 9:28 - 9:33
    plot the first column of the data as X's
  • 9:30 - 9:35
    and the second column of the data as Y's
  • 9:33 - 9:37
    so we're just going to have a data file
  • 9:35 - 9:40
    that's two columns x and y on every line
  • 9:37 - 9:47
    and then it saves that as a figure into
  • 9:40 - 9:50
    whatever the given - oh value is okay so
  • 9:47 - 9:54
    we need a data file that's going to be
  • 9:50 - 9:56
    data dot because we want plot data dot
  • 9:54 - 9:58
    PNG and our rules said that the way you
  • 9:56 - 10:00
    go from that pattern to the dot file the
  • 9:58 - 10:03
    dot that file is just by whatever
  • 10:00 - 10:06
    follows plot so if we want plot - data
  • 10:03 - 10:08
    then we want data dot that and then this
  • 10:06 - 10:09
    file we're just gonna put in some linear
  • 10:08 - 10:14
    coordinates because why not
  • 10:09 - 10:20
    that's not linear all right and now what
  • 10:14 - 10:24
    happens if we're gonna make well mmm
  • 10:20 - 10:29
    okay so what just happened well make
  • 10:24 - 10:32
    first ran plata py with the correct
  • 10:29 - 10:35
    files to generate the PNG file and then
  • 10:32 - 10:36
    it ran PDF latex paper dot text and all
  • 10:35 - 10:39
    the stuff we see below is is the output
  • 10:36 - 10:40
    from that tool if you wanted to we
  • 10:39 - 10:42
    silence the effort from this tools we
  • 10:40 - 10:44
    don't have to like have it mess with all
  • 10:42 - 10:45
    our output but in general you notice
  • 10:44 - 10:48
    that it ran the two commands then it
  • 10:45 - 10:50
    write the random perhaps unsurprisingly
  • 10:48 - 10:52
    in the right order and if we now do LS
  • 10:50 - 10:53
    in the current directory we see that we
  • 10:52 - 10:57
    have a bunch of files that were
  • 10:53 - 10:59
    generated by PDF latex but in particular
  • 10:57 - 11:02
    we have the PNG file which was generated
  • 10:59 - 11:04
    and we have the paper dot PDF and if we
  • 11:02 - 11:06
    open the paper - a PDF file we see that
  • 11:04 - 11:07
    it has one image which has the straight
  • 11:06 - 11:09
    line
  • 11:07 - 11:11
    perhaps in and of itself not a very
  • 11:09 - 11:13
    surprising or interesting result but
  • 11:11 - 11:17
    where this gets really handy is I can do
  • 11:13 - 11:19
    things like if I type make again make
  • 11:17 - 11:22
    just says paper dot PDF is up to date it
  • 11:19 - 11:24
    does no work whenever you run make it
  • 11:22 - 11:26
    tries to do the minimal amount of work
  • 11:24 - 11:28
    in order to produce whatever you ask it
  • 11:26 - 11:30
    to produce in this case none of the
  • 11:28 - 11:32
    dependencies have changed so there's no
  • 11:30 - 11:37
    reason to rebuild the paper or to
  • 11:32 - 11:40
    rebuild the plot if I now let's say I'm
  • 11:37 - 11:45
    gonna edit paper dog texts I'm gonna add
  • 11:40 - 11:47
    hello here an hour and make then if we
  • 11:45 - 11:49
    scroll up we'll see it didn't run plot
  • 11:47 - 11:51
    op py again because I didn't need to
  • 11:49 - 11:53
    none of the dependencies change but it
  • 11:51 - 11:57
    did run PDF latex again and indeed if we
  • 11:53 - 11:59
    open the paper analysis hello over there
  • 11:57 - 12:02
    on the other hand if I were to change
  • 11:59 - 12:07
    say the data file and make this point 8
  • 12:02 - 12:09
    an hour and make then now it plots again
  • 12:07 - 12:11
    because the data changed and it
  • 12:09 - 12:14
    regenerates the PDF because the plot
  • 12:11 - 12:17
    changed and indeed the paper turns out
  • 12:14 - 12:19
    the way we expected it to so that's not
  • 12:17 - 12:22
    to say that this particular pipeline is
  • 12:19 - 12:24
    very interesting because it's not it's
  • 12:22 - 12:27
    only true very very straightforward
  • 12:24 - 12:29
    targets and rules but this can come in
  • 12:27 - 12:31
    really handy when you start building
  • 12:29 - 12:32
    larger pieces of software or there might
  • 12:31 - 12:35
    be dependencies you might even imagine
  • 12:32 - 12:38
    that if you're writing a paper one of
  • 12:35 - 12:40
    your targets might be producing this
  • 12:38 - 12:42
    data file in the first place right so
  • 12:40 - 12:45
    one of the makefile
  • 12:42 - 12:48
    targets might be run my experiment right
  • 12:45 - 12:50
    run my benchmark and stick the the data
  • 12:48 - 12:53
    points that come out into this file and
  • 12:50 - 12:55
    then plot the results and then and then
  • 12:53 - 12:58
    and then and then all the way until you
  • 12:55 - 13:00
    end up with a final paper and what's
  • 12:58 - 13:01
    nice about this is first of all you
  • 13:00 - 13:02
    don't have to remember all the commands
  • 13:01 - 13:05
    to run you don't have to write them down
  • 13:02 - 13:08
    anywhere but also the tool takes care of
  • 13:05 - 13:10
    doing the minimal amount of work needed
  • 13:08 - 13:12
    often you'll find things like they'll be
  • 13:10 - 13:15
    too there'll be sub commands to make
  • 13:12 - 13:16
    like make tests right which is going to
  • 13:15 - 13:19
    compile your entire piece of software
  • 13:16 - 13:21
    and also run the tests there might be
  • 13:19 - 13:23
    things like make release
  • 13:21 - 13:25
    which builds it with optimizations
  • 13:23 - 13:28
    turned on and creates a tarball and
  • 13:25 - 13:29
    uploads that somewhere right so it's
  • 13:28 - 13:31
    gonna do the whole pipeline for you the
  • 13:29 - 13:33
    idea is to reduce the effort that you
  • 13:31 - 13:40
    have to do as any part of your build
  • 13:33 - 13:43
    process now what we saw here was a very
  • 13:40 - 13:45
    straightforward example of dependencies
  • 13:43 - 13:47
    right so we saw here that you could
  • 13:45 - 13:49
    declare files as dependencies but you
  • 13:47 - 13:50
    Kosar declare sort of transitive
  • 13:49 - 13:52
    dependencies right I depend on this
  • 13:50 - 13:54
    thing which is generated by this other
  • 13:52 - 13:57
    target very often when you work with
  • 13:54 - 14:00
    dependencies in the in the larger area
  • 13:57 - 14:02
    of software you'll find that your your
  • 14:00 - 14:04
    system ends up having many different
  • 14:02 - 14:06
    types of dependencies some of these are
  • 14:04 - 14:09
    files like we saw here some of them are
  • 14:06 - 14:11
    programs right like this sort of
  • 14:09 - 14:14
    implicitly depends on Python being
  • 14:11 - 14:16
    installed on my machine some of it might
  • 14:14 - 14:18
    be libraries right you might depend on
  • 14:16 - 14:20
    something like matplotlib which we
  • 14:18 - 14:22
    depend on here some of them might be
  • 14:20 - 14:25
    system libraries like open SSL or open
  • 14:22 - 14:29
    SSH or like low-level crypto libraries
  • 14:25 - 14:31
    and you don't necessarily declare all of
  • 14:29 - 14:33
    them very often there's sort of an an
  • 14:31 - 14:35
    assumption about what is installed on
  • 14:33 - 14:38
    the given system what you'll find is
  • 14:35 - 14:39
    that for most places where you have
  • 14:38 - 14:42
    dependencies there are tools for
  • 14:39 - 14:44
    managing those dependencies for you and
  • 14:42 - 14:46
    very often these systems you might
  • 14:44 - 14:49
    depend on are stored in what are known
  • 14:46 - 14:52
    as repositories so repository is just a
  • 14:49 - 14:55
    collection of things usually related
  • 14:52 - 14:57
    that you can install that's basically
  • 14:55 - 14:58
    all a repository is and you might be
  • 14:57 - 15:01
    familiar with some of them already
  • 14:58 - 15:03
    right so some examples of repositories
  • 15:01 - 15:06
    are pi PI which is a well-known
  • 15:03 - 15:08
    repository for Python packages rubygems
  • 15:06 - 15:11
    which is similar for ruby crates or io
  • 15:08 - 15:14
    for rust NPM for nodejs
  • 15:11 - 15:16
    but other things the repositories too
  • 15:14 - 15:19
    right like there are positives for
  • 15:16 - 15:22
    cryptographic keys like key base there
  • 15:19 - 15:24
    are repositories for system installed
  • 15:22 - 15:27
    packages like if you ever use the apt
  • 15:24 - 15:29
    tool in Ubuntu or in Debian you are
  • 15:27 - 15:31
    interacting with a package repository
  • 15:29 - 15:33
    where people who have written like
  • 15:31 - 15:35
    programs and libraries upload them so
  • 15:33 - 15:38
    that you can then install them
  • 15:35 - 15:40
    similarly you might have repositories
  • 15:38 - 15:42
    are entirely open right so the Ubuntu
  • 15:40 - 15:45
    repositories for example are usually
  • 15:42 - 15:46
    provided by the Ubuntu developers but in
  • 15:45 - 15:47
    Arch Linux there might there is
  • 15:46 - 15:50
    something called the arch user
  • 15:47 - 15:52
    repository where users can just share
  • 15:50 - 15:53
    their own libraries and their own
  • 15:52 - 15:55
    packages themselves. Very often,
  • 15:53 - 15:58
    repositories are either sort of managed
  • 15:55 - 16:00
    or they are just entirely open and you
  • 15:58 - 16:02
    should often be aware of this because if
  • 16:00 - 16:04
    you're using an entirely open repository
  • 16:02 - 16:06
    maybe the security guarantees you get
  • 16:04 - 16:09
    from that are less than what you get in
  • 16:06 - 16:11
    a controlled repository one thing you'll
  • 16:09 - 16:14
    notice if you start using repositories
  • 16:11 - 16:17
    is a very often software is versioned
  • 16:14 - 16:18
    and what I mean by version well you
  • 16:17 - 16:20
    might have seen this for stuff like
  • 16:18 - 16:25
    browsers right where there might be
  • 16:20 - 16:34
    something like starting like Chrome
  • 16:25 - 16:38
    version 64 dot zero dot two zero one 903
  • 16:34 - 16:44
    24 right this is a version number it
  • 16:38 - 16:46
    might there's a dot here this is one
  • 16:44 - 16:50
    kind of version number. But, sometimes, if
  • 16:46 - 16:52
    you start, I don't know, like Photoshop or
  • 16:50 - 16:54
    you start any other tool, there might be
  • 16:52 - 16:58
    other kind of versions that are, like,
  • 16:54 - 17:00
    8.1 dot seven right these version
  • 16:58 - 17:01
    numbers are usually numerical but not
  • 17:00 - 17:03
    always sometimes they have hashes in
  • 17:01 - 17:05
    them for example to refer to git commits
  • 17:03 - 17:07
    but you might wonder why do we have
  • 17:05 - 17:09
    these why is it even important that you
  • 17:07 - 17:11
    add a number to software that you
  • 17:09 - 17:16
    release the primary reason for this is
  • 17:11 - 17:19
    because it enables me to know whether my
  • 17:16 - 17:21
    software would break imagine that I have
  • 17:19 - 17:25
    a dependency on a library that Jose has
  • 17:21 - 17:27
    written right and Jose is constantly
  • 17:25 - 17:28
    doing changes to his library because he
  • 17:27 - 17:30
    wants to make it better and he decides
  • 17:28 - 17:32
    that one of the functions that his
  • 17:30 - 17:35
    library exposes has a bad name so he
  • 17:32 - 17:39
    renames it my software suddenly stops
  • 17:35 - 17:41
    working right because I my library calls
  • 17:39 - 17:43
    a function on Jose's library but that
  • 17:41 - 17:45
    function no longer exists depending on
  • 17:43 - 17:48
    which version people have installed of
  • 17:45 - 17:50
    Jose's library versions helps
  • 17:48 - 17:52
    because I can say I depend on this
  • 17:50 - 17:55
    version of Jose's library and there has
  • 17:52 - 17:58
    to be some rules around what is Jose
  • 17:55 - 18:00
    allowed to do within a given version if
  • 17:58 - 18:02
    he makes a change that I can no longer
  • 18:00 - 18:04
    rely on his version has to change in
  • 18:02 - 18:07
    some way
  • 18:04 - 18:10
    there are many thoughts on exactly how
  • 18:07 - 18:12
    this should work like what are the rules
  • 18:10 - 18:14
    for publishing new versions how do they
  • 18:12 - 18:18
    change the version numbers um some of
  • 18:14 - 18:20
    them are just dictated by time so for
  • 18:18 - 18:22
    example if you look at browsers they
  • 18:20 - 18:24
    very often have time versions that look
  • 18:22 - 18:26
    like this they have a version number on
  • 18:24 - 18:29
    the far left that's just like which
  • 18:26 - 18:30
    release and then they have sort of an
  • 18:29 - 18:33
    incremental number that is usually zero
  • 18:30 - 18:37
    and then they have a date at the end
  • 18:33 - 18:40
    right so this is March 24th 2019 for
  • 18:37 - 18:45
    some reason and usually that will
  • 18:40 - 18:48
    indicate that this is version 64 of
  • 18:45 - 18:51
    Firefox from this date and then if they
  • 18:48 - 18:52
    release sort of patches or hot fixes for
  • 18:51 - 18:54
    security bugs they might increment the
  • 18:52 - 18:59
    date but keep the version of the at the
  • 18:54 - 19:01
    left the same and people have strong
  • 18:59 - 19:03
    strong opinions on exactly what the
  • 19:01 - 19:05
    scheme should be and you sort of depend
  • 19:03 - 19:08
    on knowing what schemes other people use
  • 19:05 - 19:10
    right if I don't know what scheme Jose
  • 19:08 - 19:12
    is using for changing his versions
  • 19:10 - 19:14
    maybe I just have to say you have to run
  • 19:12 - 19:18
    like eight one seven of Jose's software
  • 19:14 - 19:19
    otherwise I cannot build my software but
  • 19:18 - 19:22
    this is a problem, too, right?
  • 19:19 - 19:24
    Imagine that, Jose, as a responsible
  • 19:22 - 19:27
    developer of his library, and he finds
  • 19:24 - 19:29
    the security bug and he fixes it but it
  • 19:27 - 19:31
    doesn't change the external interfaces
  • 19:29 - 19:34
    library no functions changed no types
  • 19:31 - 19:37
    change then I want people to be building
  • 19:34 - 19:39
    my software with his new version and it
  • 19:37 - 19:41
    just so happens that building mine works
  • 19:39 - 19:43
    just fine with his new version because
  • 19:41 - 19:47
    that particular version didn't change
  • 19:43 - 19:49
    anything I depended on so one attempted
  • 19:47 - 19:51
    solution to this is something called
  • 19:49 - 19:53
    semantic versioning. So, in semantic
  • 19:51 - 19:55
    versioning, we give each of the numbers
  • 19:53 - 19:57
    separated by dots in a version number, a
  • 19:55 - 20:00
    particular meaning. And, we give a
  • 19:57 - 20:01
    contract for when you have to increment
  • 20:00 - 20:07
    the different numbers
  • 20:01 - 20:15
    in particular in semantic versioning we
  • 20:07 - 20:20
    call this the major version we call this
  • 20:15 - 20:26
    the minor version and we call this the
  • 20:20 - 20:30
    patch version and the rules around this
  • 20:26 - 20:33
    are as follows if you make a change to
  • 20:30 - 20:36
    whatever your software is and and the
  • 20:33 - 20:38
    change you made is entirely backwards
  • 20:36 - 20:41
    compatible right like it does not add
  • 20:38 - 20:44
    anything it does not remove anything it
  • 20:41 - 20:47
    does not rename anything externally it
  • 20:44 - 20:50
    is as if nothing changed then you only
  • 20:47 - 20:52
    increment the patch number nothing else
  • 20:50 - 20:55
    so usually security fixes for example
  • 20:52 - 20:58
    will increment the patch number if you
  • 20:55 - 20:59
    add something to your library I'm just
  • 20:58 - 21:01
    gonna call them libraries because
  • 20:59 - 21:04
    usually libraries are the things where
  • 21:01 - 21:06
    this matters so for a library if you add
  • 21:04 - 21:08
    something to the library you increment
  • 21:06 - 21:11
    the minor version and you set the patch
  • 21:08 - 21:13
    to zero so in this case if we were to do
  • 21:11 - 21:16
    a minor release the next minor release
  • 21:13 - 21:19
    version number would be eight to zero
  • 21:16 - 21:23
    and the reason we do this is because I
  • 21:19 - 21:26
    might have a dependency on a feature the
  • 21:23 - 21:28
    josè added in a 2-0 which means you
  • 21:26 - 21:30
    can't build my software with eight one
  • 21:28 - 21:33
    seven that would not be okay
  • 21:30 - 21:34
    even though if you if I had written it
  • 21:33 - 21:37
    towards eight one seven you could run it
  • 21:34 - 21:39
    with a 2-0 the reverse is not true
  • 21:37 - 21:42
    because it might not have been added yet
  • 21:39 - 21:44
    and then finally the major version you
  • 21:42 - 21:49
    increment if you make a backwards
  • 21:44 - 21:51
    incompatible change where if my software
  • 21:49 - 21:53
    used to work with whatever version you
  • 21:51 - 21:54
    had and then you make a change that
  • 21:53 - 21:57
    means that my software might no longer
  • 21:54 - 21:58
    work such as removing a function or
  • 21:57 - 22:01
    renaming it then you increment the major
  • 21:58 - 22:03
    version and set minor and patch to zero
  • 22:01 - 22:07
    so the next major version here would be
  • 22:03 - 22:10
    nine zero zero taken together these
  • 22:07 - 22:12
    allow us to do really nice things when
  • 22:10 - 22:14
    setting what our dependencies are in
  • 22:12 - 22:16
    particular if I depend on a
  • 22:14 - 22:18
    particular version of someone's library
  • 22:16 - 22:21
    rather than saying it has to be exactly
  • 22:18 - 22:23
    this version what I'm really saying is
  • 22:21 - 22:28
    it has to be the same major version and
  • 22:23 - 22:31
    at least the same minor version and the
  • 22:28 - 22:33
    patch can be whatever this means that if
  • 22:31 - 22:36
    I have a dependency on Jose software
  • 22:33 - 22:39
    then any later release that is still
  • 22:36 - 22:42
    within the same major is fine that
  • 22:39 - 22:45
    includes keep in mind an earlier version
  • 22:42 - 22:47
    assuming that the minor is the same
  • 22:45 - 22:49
    imagine that you are saw on some older
  • 22:47 - 22:52
    computer that has like version eight one
  • 22:49 - 22:54
    three in theory my software should work
  • 22:52 - 22:57
    just fine with eight one three as well
  • 22:54 - 22:58
    it might have whatever bug the Jose
  • 22:57 - 23:00
    fixed in between like whatever security
  • 22:58 - 23:02
    issue but this has the nice property
  • 23:00 - 23:04
    that now you can share dependencies
  • 23:02 - 23:06
    between many different pieces of
  • 23:04 - 23:09
    software on your machine if you have
  • 23:06 - 23:11
    version eight-30 installed and there are
  • 23:09 - 23:12
    bunch of different software that like
  • 23:11 - 23:14
    one requires eight one seven one
  • 23:12 - 23:17
    requires eight two four one requires
  • 23:14 - 23:18
    eight zero one all of them can use the
  • 23:17 - 23:23
    same version of that dependencies you
  • 23:18 - 23:27
    only needed installed once one of the
  • 23:23 - 23:29
    most common or one of the most familiar
  • 23:27 - 23:31
    perhaps examples of this kind of
  • 23:29 - 23:33
    semantic versioning is if you look at
  • 23:31 - 23:36
    the Python versioning so many of you may
  • 23:33 - 23:38
    have come across this where python 3 and
  • 23:36 - 23:40
    python 2 are not compatible with one
  • 23:38 - 23:43
    another they're not backwards compatible
  • 23:40 - 23:46
    if you write code in Python 2 you try to
  • 23:43 - 23:48
    run in Python 3 it might not work there
  • 23:46 - 23:51
    are some cases where it will but that is
  • 23:48 - 23:53
    more accidental than anything else and
  • 23:51 - 23:56
    Python actually follows semantic
  • 23:53 - 23:59
    versioning at least mostly and so if you
  • 23:56 - 24:02
    write software that runs on Python 3.5
  • 23:59 - 24:05
    then it should also work in 3.6 3.7 and
  • 24:02 - 24:07
    3.8 it will not necessarily work in
  • 24:05 - 24:10
    Python 4 although that will hopefully be
  • 24:07 - 24:14
    a long time away but if you write code
  • 24:10 - 24:18
    for Python 3.5 it will it will possibly
  • 24:14 - 24:20
    not run on Python 3.4 so one thing you
  • 24:18 - 24:22
    will see many software projects do is
  • 24:20 - 24:24
    they try to bring the version
  • 24:22 - 24:27
    requirements they have as low as
  • 24:24 - 24:30
    possible if you can depend on major
  • 24:27 - 24:31
    and then minor in patch zero zero that
  • 24:30 - 24:34
    is the best possible dependency you can
  • 24:31 - 24:36
    have because it is completely liberal as
  • 24:34 - 24:38
    to which version of that major you're
  • 24:36 - 24:40
    depending on sometimes this is hard
  • 24:38 - 24:42
    right sometimes you genuinely need a
  • 24:40 - 24:44
    feature that was added but the lower you
  • 24:42 - 24:48
    can get the better it is for those who
  • 24:44 - 24:48
    want to depend on your software in turn
  • 24:49 - 24:53
    when working with these sort of
  • 24:51 - 24:55
    dependency management systems or in with
  • 24:53 - 24:58
    versioning in general you'll often come
  • 24:55 - 25:00
    across this notion of lock files you
  • 24:58 - 25:01
    might have seen this where like you try
  • 25:00 - 25:04
    to do something and it says like cannot
  • 25:01 - 25:06
    reconcile versions or you get an error
  • 25:04 - 25:09
    like lock file already exists these are
  • 25:06 - 25:11
    often somewhat different topics but in
  • 25:09 - 25:13
    general the notion of a lock file is to
  • 25:11 - 25:16
    make sure that you don't accidentally
  • 25:13 - 25:19
    update something the lock file at its
  • 25:16 - 25:20
    core is really just a list of your
  • 25:19 - 25:23
    dependencies and which version of them
  • 25:20 - 25:25
    you are currently using right so my
  • 25:23 - 25:27
    version string might be eight one seven
  • 25:25 - 25:30
    and the latest version like on the
  • 25:27 - 25:33
    internet somewhere might be a three zero
  • 25:30 - 25:35
    but whatever is installed on my system
  • 25:33 - 25:36
    is not necessarily one of those two it
  • 25:35 - 25:39
    might be like eight two four or
  • 25:36 - 25:42
    something like that and the lock file
  • 25:39 - 25:45
    will then say dependency josè version
  • 25:42 - 25:48
    eight to four and the reason you want to
  • 25:45 - 25:51
    lock file there can be many one of them
  • 25:48 - 25:55
    is that you might want your builds to be
  • 25:51 - 25:58
    fast if every single time you try to
  • 25:55 - 25:59
    build your project whatever tool you
  • 25:58 - 26:01
    were using download the latest version
  • 25:59 - 26:03
    and then compile it and then compile
  • 26:01 - 26:05
    your thing you might wait for a really
  • 26:03 - 26:07
    long time each time depending on the
  • 26:05 - 26:10
    release cycle of your dependencies if
  • 26:07 - 26:10
    you use a lock file then unless the
  • 26:10 - 26:12
    version
  • 26:10 - 26:14
    unless you've updated the version in
  • 26:12 - 26:16
    your lock file it'll just use whatever
  • 26:14 - 26:19
    it built previously for that dependency
  • 26:16 - 26:22
    and your sort of development cycle can
  • 26:19 - 26:25
    be a lot faster another reason to use
  • 26:22 - 26:27
    lock files is to get reproducible builds
  • 26:25 - 26:30
    imagine that I produce some kind of
  • 26:27 - 26:33
    security related software and I very
  • 26:30 - 26:35
    carefully audited my dependencies and I
  • 26:33 - 26:39
    produce like a signed binary of like
  • 26:35 - 26:40
    here is thus like a sworn statement for
  • 26:39 - 26:43
    me that this
  • 26:40 - 26:46
    version is secure if I didn't include a
  • 26:43 - 26:48
    lock file then by the time someone else
  • 26:46 - 26:50
    installs my program they might get a
  • 26:48 - 26:51
    later version of their pendency and
  • 26:50 - 26:54
    maybe that later version as I've been
  • 26:51 - 26:55
    hacked somehow or just has some other
  • 26:54 - 26:58
    security vulnerability that I haven't
  • 26:55 - 27:01
    had a chance to look at yet right and a
  • 26:58 - 27:03
    lock file basically allows me to freeze
  • 27:01 - 27:07
    the ecosystem as of this version that I
  • 27:03 - 27:09
    have checked the extreme version of this
  • 27:07 - 27:11
    is something called ven during when you
  • 27:09 - 27:14
    vendor your dependencies it really just
  • 27:11 - 27:16
    mean you copy/paste of them ven during
  • 27:14 - 27:18
    means take whatever dependency you care
  • 27:16 - 27:22
    about and copy it into your project
  • 27:18 - 27:24
    because that way you are entirely sure
  • 27:22 - 27:26
    that you will get that version of that
  • 27:24 - 27:28
    dependency it also means that you can
  • 27:26 - 27:30
    like make modifications to it on your
  • 27:28 - 27:32
    own but it has the downsides that now
  • 27:30 - 27:35
    you no longer get these benefits of
  • 27:32 - 27:36
    versioning right you no longer have the
  • 27:35 - 27:39
    advantage that if there are newer
  • 27:36 - 27:41
    releases of that software your users
  • 27:39 - 27:42
    might get them automatically like for
  • 27:41 - 27:49
    example when Hosea fixes his security
  • 27:42 - 27:52
    issues not that he has any of course one
  • 27:49 - 27:54
    thing you'll notice is that when talking
  • 27:52 - 27:56
    about this I've been talking about sort
  • 27:54 - 27:59
    of bigger processes around your systems
  • 27:56 - 28:01
    these are things like testing they're
  • 27:59 - 28:02
    things like checking your dependency
  • 28:01 - 28:04
    versions
  • 28:02 - 28:07
    they're also things are just setting up
  • 28:04 - 28:09
    build systems and often you don't just
  • 28:07 - 28:11
    want a local build system you want to
  • 28:09 - 28:13
    build process that includes other types
  • 28:11 - 28:15
    of systems or you want them to run even
  • 28:13 - 28:18
    when your computer is not necessarily on
  • 28:15 - 28:20
    and this is why as you start working a
  • 28:18 - 28:23
    larger and larger project you will see
  • 28:20 - 28:25
    people use this idea of continuous
  • 28:23 - 28:29
    integration and continuous integration
  • 28:25 - 28:32
    systems are essentially a cloud build
  • 28:29 - 28:34
    system the idea is that you have your
  • 28:32 - 28:36
    project stored on the internet somewhere
  • 28:34 - 28:39
    and you have set it up with some kind of
  • 28:36 - 28:42
    service that is running an ongoing thing
  • 28:39 - 28:44
    you for your project whatever it might
  • 28:42 - 28:46
    be and continuous integration can be all
  • 28:44 - 28:48
    sorts of stuff it can be stuff like
  • 28:46 - 28:50
    releasing your library to pi PI
  • 28:48 - 28:53
    automatically whenever you push to a
  • 28:50 - 28:53
    particular branch it could be things
  • 28:53 - 28:55
    like
  • 28:53 - 28:58
    run your test suite whenever someone
  • 28:55 - 29:01
    submits a pull request or it could be
  • 28:58 - 29:03
    check your code style every time you
  • 29:01 - 29:04
    commit there all sorts of things you
  • 29:03 - 29:06
    could do with continuous integration and
  • 29:04 - 29:08
    the easiest way to think about them is
  • 29:06 - 29:11
    that they're sort of event triggered
  • 29:08 - 29:13
    actions so whenever a particular event
  • 29:11 - 29:15
    happens for your a possibly for your
  • 29:13 - 29:17
    project a particular action takes place
  • 29:15 - 29:20
    where the action is usually some kind of
  • 29:17 - 29:22
    script some sequence of programs they're
  • 29:20 - 29:27
    gonna be invoked and they're gonna do
  • 29:22 - 29:30
    something this is really an umbrella
  • 29:27 - 29:32
    term that encapsulate a lot of different
  • 29:30 - 29:34
    types of services so some continuous
  • 29:32 - 29:38
    integration services are very general
  • 29:34 - 29:43
    things like Travis CI or Azure pipelines
  • 29:38 - 29:46
    or github actions are all very broad CI
  • 29:43 - 29:48
    platforms they're built to let you write
  • 29:46 - 29:51
    what you want to happen whenever any
  • 29:48 - 29:53
    event that you define happens very broad
  • 29:51 - 29:56
    systems there are some more specialized
  • 29:53 - 29:59
    systems that deal with things like
  • 29:56 - 30:02
    continuous integration coverage testing
  • 29:59 - 30:04
    so like annotate your code and show you
  • 30:02 - 30:06
    have no tests that test this piece of
  • 30:04 - 30:07
    code and they're built only for that
  • 30:06 - 30:11
    purpose or they're built only for
  • 30:07 - 30:13
    testing browser-based libraries or
  • 30:11 - 30:15
    something like that and so often you can
  • 30:13 - 30:17
    find CI tools that are built for the
  • 30:15 - 30:18
    particular project you're working on or
  • 30:17 - 30:21
    you can use one of these broader
  • 30:18 - 30:22
    providers and one thing that's nice is
  • 30:21 - 30:24
    that many of them are actually free
  • 30:22 - 30:26
    especially for open source software or
  • 30:24 - 30:30
    if you're a student you can often get
  • 30:26 - 30:33
    them for free as well in general the way
  • 30:30 - 30:36
    you use the CI system is that you add a
  • 30:33 - 30:38
    file to your repository and this file is
  • 30:36 - 30:40
    often known as a recipe and what the
  • 30:38 - 30:42
    recipe specifies is this sort of
  • 30:40 - 30:45
    dependency cycle again sort of what we
  • 30:42 - 30:47
    saw with make files it's not quite the
  • 30:45 - 30:49
    same the events instead of being files
  • 30:47 - 30:52
    might be something like when someone
  • 30:49 - 30:55
    pushes a commit or when a commit
  • 30:52 - 30:57
    contains a particular message or when
  • 30:55 - 31:01
    someone submits a pull request or
  • 30:57 - 31:03
    continuously write one example of a
  • 31:01 - 31:04
    continuous integration service that's
  • 31:03 - 31:06
    not tied to any particular change to
  • 31:04 - 31:07
    your code is something called the
  • 31:06 - 31:09
    dependable
  • 31:07 - 31:11
    you can find this on github and the
  • 31:09 - 31:14
    dependent bots is something that you
  • 31:11 - 31:16
    hook up to your your repository and it
  • 31:14 - 31:18
    will just scan whether there are newer
  • 31:16 - 31:20
    versions available of your dependencies
  • 31:18 - 31:23
    that you're not using so for example if
  • 31:20 - 31:25
    I was depending on eight one seven and I
  • 31:23 - 31:27
    had a lock file that locked it to eight
  • 31:25 - 31:29
    two four and then eight three zero is
  • 31:27 - 31:31
    released the dependable will go you
  • 31:29 - 31:32
    should update your log file and then
  • 31:31 - 31:35
    submit the pull request to your
  • 31:32 - 31:36
    repository with that update this is a
  • 31:35 - 31:38
    continuous integration service it's not
  • 31:36 - 31:43
    tied to me changing anything but to the
  • 31:38 - 31:46
    ecosystem at large changing often these
  • 31:43 - 31:49
    CI systems integrate the back into your
  • 31:46 - 31:51
    project as well so very often these CI
  • 31:49 - 31:57
    services will provide things like little
  • 31:51 - 32:00
    badges so let me give an example so for
  • 31:57 - 32:01
    example here's a project I've worked on
  • 32:00 - 32:05
    recently that has continuous integration
  • 32:01 - 32:09
    set up so this project you'll notice
  • 32:05 - 32:14
    it's readme if I can zoom in here with
  • 32:09 - 32:18
    that chrome bean nope nope that's much
  • 32:14 - 32:20
    larger than I wanted here you'll see
  • 32:18 - 32:22
    that at the top of the the repositories
  • 32:20 - 32:25
    page they're a bunch of these badges and
  • 32:22 - 32:26
    they display very various types of
  • 32:25 - 32:28
    information you'll notice that I have
  • 32:26 - 32:30
    dependable running right so the
  • 32:28 - 32:32
    dependencies are currently up to date it
  • 32:30 - 32:33
    tells me about whether the test suite is
  • 32:32 - 32:36
    currently passing on the master branch
  • 32:33 - 32:40
    it tells me how much of the code is
  • 32:36 - 32:41
    coverage by tests and it tells me what
  • 32:40 - 32:43
    is the latest version of this library
  • 32:41 - 32:45
    and what is the latest version of the
  • 32:43 - 32:48
    documentation of the library that's
  • 32:45 - 32:50
    available online and all of these are
  • 32:48 - 32:52
    managed by various continues continuous
  • 32:50 - 32:54
    integration services another example
  • 32:52 - 32:56
    that some of you might find useful or
  • 32:54 - 33:01
    might even be familiar with is the
  • 32:56 - 33:03
    notion of github pages so github pages
  • 33:01 - 33:06
    is a really nice service the github
  • 33:03 - 33:14
    provides which lets you set up a CI
  • 33:06 - 33:17
    action that builds your repository as a
  • 33:14 - 33:19
    blog essentially it's it runs a static
  • 33:17 - 33:22
    site generator called Jekyll
  • 33:19 - 33:25
    and Jeckle just takes a bunch of
  • 33:22 - 33:28
    markdown files and then produces a
  • 33:25 - 33:30
    complete website and that as a part of
  • 33:28 - 33:32
    get up pages they will also upload that
  • 33:30 - 33:35
    to get up servers and make it available
  • 33:32 - 33:37
    at a particular domain and this is
  • 33:35 - 33:39
    actually how the class website works
  • 33:37 - 33:42
    class website is not a bunch of like
  • 33:39 - 33:48
    HTML pages that we manage instead
  • 33:42 - 33:50
    there's a repository missing semester so
  • 33:48 - 33:54
    if you look at the missing semester
  • 33:50 - 33:58
    repository you will see if i zoom out a
  • 33:54 - 34:02
    little here that this just has a bunch
  • 33:58 - 34:08
    of markdown files right it has saket
  • 34:02 - 34:11
    20/20 metaprogramming md so this is the
  • 34:08 - 34:14
    if I go to raw here this is the raw
  • 34:11 - 34:16
    markdown for today's lecture so this is
  • 34:14 - 34:19
    the way that I write the lecture notes
  • 34:16 - 34:21
    and then I commit that to the repository
  • 34:19 - 34:25
    we have and I push it and whenever a
  • 34:21 - 34:28
    push happens the github pages CI is
  • 34:25 - 34:32
    gonna run the build script for github
  • 34:28 - 34:34
    pages and produces the website for our
  • 34:32 - 34:38
    class without me having to do any
  • 34:34 - 34:47
    additional steps to make that happen and
  • 34:38 - 34:49
    so yeah sorry good yeah so so Jekyll
  • 34:47 - 34:55
    it's using a tool called Jekyll which is
  • 34:49 - 34:56
    a tool that takes a directory structure
  • 34:55 - 34:59
    that contains markdown files and
  • 34:56 - 35:02
    produces a website it produces like HTML
  • 34:59 - 35:04
    files and then as a part of the action
  • 35:02 - 35:06
    it takes those files and uploads them to
  • 35:04 - 35:08
    github servers add a particular domain
  • 35:06 - 35:12
    and usually that's the domain under like
  • 35:08 - 35:15
    github I oh that they control and then I
  • 35:12 - 35:24
    have set missing semester to point to
  • 35:15 - 35:27
    the github domain I want to give you one
  • 35:24 - 35:29
    aside on testing because it's something
  • 35:27 - 35:31
    that many of you may be familiar with
  • 35:29 - 35:33
    from before right you have a rough idea
  • 35:31 - 35:35
    of what testing is you
  • 35:33 - 35:37
    run the test before you've seen a test
  • 35:35 - 35:39
    fail you know like the basics of it or
  • 35:37 - 35:43
    maybe you've never seen a test fail in
  • 35:39 - 35:45
    case congratulations but as you as you
  • 35:43 - 35:48
    get to more advanced projects though
  • 35:45 - 35:50
    you'll find that people have a lot of
  • 35:48 - 35:53
    terminology around testing and testing
  • 35:50 - 35:55
    is a pretty like deep subject that you
  • 35:53 - 35:57
    could spend many many hours trying to
  • 35:55 - 35:58
    understand the ins and outs of and I'm
  • 35:57 - 36:00
    not going to go through it in
  • 35:58 - 36:02
    excruciating detail but there are a
  • 36:00 - 36:04
    couple of words that I think it's useful
  • 36:02 - 36:06
    to know what mean and the first of these
  • 36:04 - 36:09
    is a test suite so a test suite is a
  • 36:06 - 36:12
    very straightforward name for all of the
  • 36:09 - 36:14
    tests in a program it's really just a
  • 36:12 - 36:17
    suite of tests it's a large collection
  • 36:14 - 36:20
    of tests that usually are run as a unit
  • 36:17 - 36:23
    and there are different types of tests
  • 36:20 - 36:25
    that often make up a test suite the
  • 36:23 - 36:28
    first of these is what's known as a unit
  • 36:25 - 36:31
    test a unit test is a often usually
  • 36:28 - 36:35
    fairly small test of self-contained
  • 36:31 - 36:37
    tests the tests a single feature what
  • 36:35 - 36:39
    exactly a feature might mean is a little
  • 36:37 - 36:41
    bit up to the project but the idea is
  • 36:39 - 36:45
    that should be sort of a micro test that
  • 36:41 - 36:46
    only tests a very particular thing then
  • 36:45 - 36:49
    you have the larger tests that are known
  • 36:46 - 36:51
    as integration tests integration tests
  • 36:49 - 36:54
    try to test the interaction between
  • 36:51 - 36:57
    different subsystems of a program so
  • 36:54 - 37:00
    this might be something like an example
  • 36:57 - 37:03
    of a unit test might be if you're
  • 37:00 - 37:06
    writing an HTML parser to the unit test
  • 37:03 - 37:10
    might be test that it can parse an HTML
  • 37:06 - 37:14
    tag an integration test might be here's
  • 37:10 - 37:15
    an HTML document parse it right so that
  • 37:14 - 37:16
    is going to be the interview the
  • 37:15 - 37:20
    integration of multiple of the
  • 37:16 - 37:23
    subsystems of the parser you also have a
  • 37:20 - 37:25
    notion of regression tests regression
  • 37:23 - 37:28
    tests are tests that test things that
  • 37:25 - 37:31
    were broken in the past so imagine that
  • 37:28 - 37:33
    someone submits some kind of issue to
  • 37:31 - 37:39
    you and says your library breaks if I
  • 37:33 - 37:41
    give it a marquee tag and that makes you
  • 37:39 - 37:43
    sad so you want to fix it so you fix
  • 37:41 - 37:46
    your parser to now support marquee tags
  • 37:43 - 37:47
    but then you want to add a test to your
  • 37:46 - 37:48
    test suite
  • 37:47 - 37:51
    the checks that you can parse marquee
  • 37:48 - 37:53
    tags the reason for this is so that in
  • 37:51 - 37:57
    the future you don't accidentally
  • 37:53 - 37:58
    reintroduce that bug. So that is what
  • 37:57 - 38:00
    a regression tests are for and over time
  • 37:58 - 38:01
    your project is gonna build up more and
  • 38:00 - 38:03
    more of these, and they're nice because
  • 38:01 - 38:07
    they prevent your project from
  • 38:03 - 38:10
    regressing to earlier bugs. The last one
  • 38:07 - 38:16
    I want to mention is a concept called
  • 38:10 - 38:18
    mocking. So mocking is the idea of being
  • 38:16 - 38:21
    able to replace parts of your system
  • 38:18 - 38:26
    with a sort of dummy version of itself
  • 38:21 - 38:29
    that behaves in a way that you control. A
  • 38:26 - 38:33
    common example of this is you're writing
  • 38:29 - 38:36
    something that does, oh I don't know, file
  • 38:33 - 38:37
    copying over SSH. Right? This is a tool
  • 38:36 - 38:40
    that you've written that does file
  • 38:37 - 38:42
    copying over SSH there are many things
  • 38:40 - 38:43
    you might want to mock here. For example,
  • 38:42 - 38:45
    when running your test suite you
  • 38:43 - 38:47
    probably don't actually care that
  • 38:45 - 38:49
    there's a network there. Right? You don't
  • 38:47 - 38:51
    need to have to like set up TCP ports
  • 38:49 - 38:54
    and stuff, so instead you're gonna mock
  • 38:51 - 38:56
    the network. The way this usually works
  • 38:54 - 38:58
    is that, somewhere in your library, you
  • 38:56 - 39:00
    have something that like opens a
  • 38:58 - 39:02
    connection, or reads from the connection,
  • 39:00 - 39:03
    or writes to the connection, and you're
  • 39:02 - 39:06
    gonna overwrite those functions
  • 39:03 - 39:08
    internally in your library with
  • 39:06 - 39:10
    functions that you've written just for
  • 39:08 - 39:12
    the purposes of testing, where the read
  • 39:10 - 39:14
    function just like returns the data, and
  • 39:12 - 39:15
    the write function just drops the data
  • 39:14 - 39:18
    on the floor, or something like that.
  • 39:15 - 39:20
    Similarly, you can write a mocking
  • 39:18 - 39:21
    function for the SSH functionality. You
  • 39:20 - 39:22
    could write something that does not
  • 39:21 - 39:25
    actually do encryption, it doesn't talk
  • 39:22 - 39:27
    to the network: it just like takes bytes
  • 39:25 - 39:29
    in here and just magically they pop out
  • 39:27 - 39:30
    the other side, and you can ignore
  • 39:29 - 39:32
    everything that's between, because for
  • 39:30 - 39:34
    the purpose of copying a file, if you
  • 39:32 - 39:37
    just wanted to test that functionality,
  • 39:34 - 39:41
    the stuff below doesn't matter for that
  • 39:37 - 39:43
    test, and you might mock it away. Usually,
  • 39:41 - 39:44
    in any given language, there are tools
  • 39:43 - 39:50
    that let you build these kind of mocking
  • 39:44 - 39:51
    abstractions pretty easily. That is the
  • 39:50 - 39:54
    end of what I wanted to talk about
  • 39:51 - 39:56
    metaprogramming, but this is a very, very
  • 39:54 - 39:59
    broad subject. Things like continuous
  • 39:56 - 40:00
    integration, build systems, there are so
  • 39:59 - 40:02
    many out there
  • 40:00 - 40:04
    that can let you do so many interesting
  • 40:02 - 40:05
    things with your projects, so I highly
  • 40:04 - 40:11
    recommend that you start looking into it
  • 40:05 - 40:13
    a little. The exercises are sort of all
  • 40:11 - 40:16
    over the place, and I mean that in a good
  • 40:13 - 40:18
    way. They're intended to try to just show
  • 40:16 - 40:21
    you the kind of possibilities that exist
  • 40:18 - 40:23
    for build working with these kind of
  • 40:21 - 40:26
    processes so for example the last
  • 40:23 - 40:28
    exercise has you write one of these
  • 40:26 - 40:31
    continuous integration actions yourself
  • 40:28 - 40:34
    where it you decide what the event be
  • 40:31 - 40:36
    and you decide what the action be but
  • 40:34 - 40:37
    try to actually build one and this can
  • 40:36 - 40:40
    be something that you might find useful
  • 40:37 - 40:43
    in your project the example I given the
  • 40:40 - 40:46
    exercises is try to build an action that
  • 40:43 - 40:47
    runs like right good or pro Slynt one of
  • 40:46 - 40:50
    the linters result for the english
  • 40:47 - 40:52
    language on your repository and if you
  • 40:50 - 40:56
    do like we could enable that for the
  • 40:52 - 40:58
    class repository so that our lecture
  • 40:56 - 41:00
    notes are actually well written right
  • 40:58 - 41:01
    and this is one other thing that's nice
  • 41:00 - 41:04
    about this kind of continuous
  • 41:01 - 41:06
    integration testing is that you can
  • 41:04 - 41:09
    collaborate between projects if you
  • 41:06 - 41:10
    write one I can use it in my project and
  • 41:09 - 41:12
    there's a really handy feature where you
  • 41:10 - 41:15
    can build this ecosystem of improving
  • 41:12 - 41:33
    everything any questions about any of
  • 41:15 - 41:36
    the stuff we record today yeah so the
  • 41:33 - 41:38
    question is why do we have both make and
  • 41:36 - 41:41
    see make what do they do and is there a
  • 41:38 - 41:45
    reason for them to talk together so so
  • 41:41 - 41:47
    see make I don't actually know what the
  • 41:45 - 41:50
    tagline for C make is anymore but it's
  • 41:47 - 41:55
    sort of like a better make for C as the
  • 41:50 - 41:57
    name implies C make generally
  • 41:55 - 41:59
    understands the layout of C projects a
  • 41:57 - 42:02
    little bit better than make Falls do
  • 41:59 - 42:04
    they're sort of built to try to parse
  • 42:02 - 42:05
    out what the structure of your
  • 42:04 - 42:07
    dependencies are what the rules from
  • 42:05 - 42:08
    going to one to the other is it also
  • 42:07 - 42:11
    integrates a little bit nicer with
  • 42:08 - 42:13
    things like system libraries so C may
  • 42:11 - 42:15
    can do things like detect
  • 42:13 - 42:16
    given libraries available on your
  • 42:15 - 42:18
    computer or if it's available at
  • 42:16 - 42:20
    multiple different paths it tries to
  • 42:18 - 42:22
    find which of those paths it's present
  • 42:20 - 42:24
    on on this system and then link it
  • 42:22 - 42:28
    appropriately so see make is a little
  • 42:24 - 42:30
    bit smarter than make is make will only
  • 42:28 - 42:32
    do whatever you put in the make file not
  • 42:30 - 42:34
    entirely true there are things called
  • 42:32 - 42:36
    implicit rules that are like built-in
  • 42:34 - 42:38
    rules in make but they're pretty dumb
  • 42:36 - 42:41
    whereas emic tries to be able to be a
  • 42:38 - 42:43
    larger build system that is opinionated
  • 42:41 - 42:46
    by default to work for C projects
  • 42:43 - 42:50
    similarly there's a tool called maven so
  • 42:46 - 42:52
    maven and ant which is another project
  • 42:50 - 42:55
    they are both built for Java projects
  • 42:52 - 42:56
    they understand how Java code interacts
  • 42:55 - 42:59
    with one another how you structure Java
  • 42:56 - 43:02
    programs and they're built for that task
  • 42:59 - 43:05
    very often at least when I use make I
  • 43:02 - 43:08
    use make sort of at the top and then
  • 43:05 - 43:09
    make my call other tools that build
  • 43:08 - 43:12
    whatever subsystem they know how to
  • 43:09 - 43:15
    build right like my make file might call
  • 43:12 - 43:16
    cargo to build a rust program and then
  • 43:15 - 43:19
    call see make to build some like see
  • 43:16 - 43:21
    dependency of that but then at the top
  • 43:19 - 43:23
    like I'm gonna do some stuff at the end
  • 43:21 - 43:25
    after the programs have built and that
  • 43:23 - 43:27
    might just be like run a benchmark which
  • 43:25 - 43:29
    is in the rust code and then like plot
  • 43:27 - 43:31
    it using the C code or something like
  • 43:29 - 43:34
    that right so for me make you sort of
  • 43:31 - 43:36
    the glue at the top that I might write
  • 43:34 - 43:41
    usually if your make file gets very
  • 43:36 - 43:42
    large there's a better tool would you'll
  • 43:41 - 43:45
    find it like big companies for example
  • 43:42 - 43:48
    is they often have one build system that
  • 43:45 - 43:49
    manages all of their software so if you
  • 43:48 - 43:52
    look at Google for example they have
  • 43:49 - 43:54
    this open source system called basil and
  • 43:52 - 43:57
    I don't think Google literally uses
  • 43:54 - 44:00
    basil inside of Google but it's sort of
  • 43:57 - 44:02
    based on what they use internally and it
  • 44:00 - 44:05
    really just its intended to manage the
  • 44:02 - 44:09
    entire build of everything Google has
  • 44:05 - 44:12
    and basil in particular is built to be I
  • 44:09 - 44:14
    think they call it like a polyglot build
  • 44:12 - 44:16
    framework so the idea is that it works
  • 44:14 - 44:18
    for many different languages there's
  • 44:16 - 44:20
    like an implement there's a module for
  • 44:18 - 44:21
    basil for this language and that
  • 44:20 - 44:24
    language in that language but they all
  • 44:21 - 44:26
    integrate with the same basil framework
  • 44:24 - 44:28
    which then knows how to integrate
  • 44:26 - 44:33
    dependencies between different libraries
  • 44:28 - 44:33
    and different languages get a question
  • 44:39 - 44:42
    sure
  • 44:41 - 44:48
    so when you say expressions you mean the
  • 44:42 - 44:48
    things in this file or yeah so these are
  • 44:49 - 44:57
    so make files are their own language
  • 44:53 - 45:00
    they are it's a pretty weird language
  • 44:57 - 45:03
    like it has a lot of weird exceptions in
  • 45:00 - 45:04
    many ways it's weird just like bash is
  • 45:03 - 45:06
    weird but in different ways which is
  • 45:04 - 45:08
    even worse like when you're writing a
  • 45:06 - 45:10
    make file you sort of you can sort of
  • 45:08 - 45:11
    think like you're writing bash but
  • 45:10 - 45:14
    you're not because it's broken in
  • 45:11 - 45:17
    different ways but but it is its own
  • 45:14 - 45:20
    language and the way that make files are
  • 45:17 - 45:21
    generally structured is that you have a
  • 45:20 - 45:25
    sequence of I think they call them
  • 45:21 - 45:29
    directives so every like the this thing
  • 45:25 - 45:32
    oops this thing is a directive and this
  • 45:29 - 45:34
    is a directive and every directive has a
  • 45:32 - 45:36
    colon somewhere and everything to the
  • 45:34 - 45:38
    left of the colon is a target and
  • 45:36 - 45:43
    everything to the right of the colon is
  • 45:38 - 45:46
    right of the colon is a dependency and
  • 45:43 - 45:49
    then all of the lines below that line
  • 45:46 - 45:52
    are the sequence of operations known as
  • 45:49 - 45:53
    the rules for once you have the
  • 45:52 - 45:55
    dependencies how do you build these
  • 45:53 - 45:59
    targets notice that make is very
  • 45:55 - 46:01
    particular that you must use a tab to
  • 45:59 - 46:04
    indent the rules if you do not make will
  • 46:01 - 46:06
    not work if they must be tabs they
  • 46:04 - 46:08
    cannot be four eight spaces must be tabs
  • 46:06 - 46:10
    and like you can have multiple
  • 46:08 - 46:13
    operations here I like I can do echo
  • 46:10 - 46:16
    hello or whatever and then they would
  • 46:13 - 46:18
    first run this and then run this there's
  • 46:16 - 46:20
    a there's an exercise for today's
  • 46:18 - 46:23
    lecture that has you try to extend this
  • 46:20 - 46:24
    make file with a couple of other targets
  • 46:23 - 46:26
    that you might find interesting that
  • 46:24 - 46:30
    goes into a little bit more detail
  • 46:26 - 46:33
    there's also some ability to execute
  • 46:30 - 46:36
    external commands to like determine what
  • 46:33 - 46:38
    the dependencies might be if your
  • 46:36 - 46:40
    dependencies are not like a static list
  • 46:38 - 46:42
    of files but it's a little limited
  • 46:40 - 46:44
    usually once you've started needing that
  • 46:42 - 47:00
    sort of stuff you might want to move to
  • 46:44 - 47:06
    a more advanced build system yeah so the
  • 47:00 - 47:09
    question is what happens if I have let's
  • 47:06 - 47:14
    say that I have library a and library B
  • 47:09 - 47:19
    and they both depend on library see but
  • 47:14 - 47:25
    library a depends on like 4.0.1 and
  • 47:19 - 47:27
    library B depends on 3 dot 4 dot 7 so
  • 47:25 - 47:29
    they both depend on C and so ideally
  • 47:27 - 47:32
    we'd like to reuse see but they depend
  • 47:29 - 47:35
    on different major versions of C what do
  • 47:32 - 47:38
    we do well what happens in this case
  • 47:35 - 47:39
    depends entirely on the system that
  • 47:38 - 47:42
    you're using the language that you're
  • 47:39 - 47:44
    using in some cases the tool would just
  • 47:42 - 47:46
    be like well I'll just pick for which
  • 47:44 - 47:49
    sort of implies that they're not really
  • 47:46 - 47:52
    using semantic versioning in some cases
  • 47:49 - 47:55
    the tool will say this is not possible
  • 47:52 - 47:58
    like if you do this it's an error and
  • 47:55 - 48:00
    the tool will tell you you either need
  • 47:58 - 48:03
    to upgrade be like have B use a newer
  • 48:00 - 48:05
    version of C or you need to downgrade a
  • 48:03 - 48:08
    you do not get to do this and
  • 48:05 - 48:12
    compilation will fail some tools are
  • 48:08 - 48:16
    gonna build two versions of C and then
  • 48:12 - 48:19
    like when it builds a it will use the
  • 48:16 - 48:20
    major four version of C and when it
  • 48:19 - 48:23
    builds B will use the major three
  • 48:20 - 48:26
    version of C one thing you end up with
  • 48:23 - 48:28
    is really weird conditions here were
  • 48:26 - 48:30
    like if C has dependencies then now you
  • 48:28 - 48:33
    have to build all of C's dependencies
  • 48:30 - 48:35
    twice to 1 for 3 and 1 for 4 and maybe
  • 48:33 - 48:37
    they share and maybe they don't you can
  • 48:35 - 48:43
    end up in particularly weird situations
  • 48:37 - 48:43
    if imagine that the library see like
  • 48:45 - 48:48
    imagine that
  • 48:49 - 48:56
    library see like rights to a file like
  • 48:53 - 48:58
    rights to some like file on disk some
  • 48:56 - 49:01
    cache stuff if you run your application
  • 48:58 - 49:04
    now and like a does something to call
  • 49:01 - 49:07
    like C dot save and B to something like
  • 49:04 - 49:09
    C adult load then suddenly your your
  • 49:07 - 49:10
    application of the bottom is not going
  • 49:09 - 49:11
    to work because the format is different
  • 49:10 - 49:13
    right
  • 49:11 - 49:16
    so these situations are often very
  • 49:13 - 49:18
    problematic and and most tools that
  • 49:16 - 49:20
    support semantic versioning will reject
  • 49:18 - 49:22
    this kind of configuration for exactly
  • 49:20 - 49:27
    that reason but it's so easy to shoot
  • 49:22 - 49:30
    yourself in the foot all right we will
  • 49:27 - 49:32
    see you again tomorrow for security keep
  • 49:30 - 49:34
    in mind again if you haven't done the
  • 49:32 - 49:36
    survey the question I care the most
  • 49:34 - 49:38
    about in the survey is what you would
  • 49:36 - 49:40
    like us to cover in the last two
  • 49:38 - 49:43
    lectures so the last two lectures are
  • 49:40 - 49:45
    for you to choose what you want us to
  • 49:43 - 49:47
    talk about and to give any questions you
  • 49:45 - 49:50
    want us to answer so please like add
  • 49:47 - 49:52
    that if you can and that's it see you
  • 49:50 - 49:52
    tomorrow
Title:
Lecture 8: Metaprogramming (2020)
Description:

more » « less
Video Language:
English
Duration:
49:53

English subtitles

Revisions